update to reflect text widget changes.
authorHavoc Pennington <hp@redhat.com>
Tue, 25 Jul 2000 23:59:38 +0000 (23:59 +0000)
committerHavoc Pennington <hp@src.gnome.org>
Tue, 25 Jul 2000 23:59:38 +0000 (23:59 +0000)
2000-07-25  Havoc Pennington  <hp@redhat.com>

* gtk/testtext.c, gtk/testtextbuffer.c: update to reflect text
widget changes.

* gtk/gtktextview.h: To be consistent with usage of "line"
throughout the API to mean "newline-terminated thingy", change
MOVEMENT_LINE to be MOVEMENT_WRAPPED_LINE, and MOVEMENT_PARAGRAPH
to MOVEMENT_LINE.

(GtkTextView): Add flags for default editability, and whether to
show the cursor. Add functions to get/set that. Add

(gtk_text_view_get_iter_location): new function

* gtk/gtktexttypes.h: Move GtkTextLine typedef from here to
gtktextlayout.h
(g_convert): Add g_convert temporarily, will go in glib in a bit

* gtk/gtktexttagtable.h: include gtktexttag.h, and define
GtkTextTagTableForeach instead of brokenly using GHFunc.
Change gtk_text_tag_table_foreach() so it doesn't use GHFunc.

* gtk/gtktexttagprivate.h: Remove GtkTextStyleValues from here,
moved to public header.

* gtk/gtktexttag.h: Rename the "elide" attribute of tags to
"invisible", since "elide" was a bad name.
(gtk_text_tag_get_priority): Added

(GtkTextStyleValues): put this in public header, along with
functions to use it.

* gtk/gtktextmarkprivate.h: Include more headers, since we no
longer include gtktextbtree.h.

* gtk/gtktextmark.h: Add gtk_text_mark_ref, gtk_text_mark_unref,
gtk_text_mark_deleted

* gtk/gtktextlayout.h: Don't include the "really private" headers,
only buffer/iter. Forward declare GtkTextLIne and GtkTextLineData
to make this possible. Now we only need to install
gtktextlayout.h, not gtktextbtree.h and gtktext*private.h.
(However the Makefile.am isn't changed yet because of the
logistics of merging gtk-hp-patches piecemeal)

* gtk/gtktextiterprivate.h: include btree header, so it compiles;
rename gtk_text_iter_get_line to gtk_text_iter_get_text_line since
gtk_text_iter_get_line is now used in the public API for a
different purpose.

* gtk/gtktextiter.h: Clean up function names to be more
consistent. Always call char offset "offset" and byte index
"index". A "line" is always a line number.

(gtk_text_iter_is_last): new function, more efficient than
the existing way to check
(gtk_text_iter_is_first): new function, also more efficient

(gtk_text_iter_up_lines, gtk_text_iter_down_lines): Remove these

(gtk_text_iter_next_char, gtk_text_iter_prev_char): Renamed from
gtk_text_iter_forward_char, etc.

(gtk_text_iter_forward_to_tag_toggle): Renamed from
forward_find_tag_toggle, since this isn't a linear search

(GtkTextCharPredicate): rename from GtkTextViewCharPredicate

(gtk_text_iter_forward_search, gtk_text_iter_backward_search):
New functions, search for a buffer substring.

* gtk/gtktextbuffer.h: Add fields to store whether a paste is
interactive and default editable (since we need to store that info
until we receive the selection data).

Remove all the _at_char and at_line etc. versions of functions;
only have iterator versions.

Add _interactive() versions of functions, that consider the
editability of text. (FIXME add interactive flag to the
insert/delete signals per Darin's suggestion)

(gtk_text_buffer_get_tag_table): new function, demand-creates the
tag table if necessary

Remove declaration of gtk_text_buffer_get_iter_from_string

(_gtk_text_buffer_get_btree): private/internal function, added.

* gtk/gtktextbtree.h: Remove forward decl of GtkTextLineData.
(gtk_text_line_is_last): new function

34 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtktextbtree.c
gtk/gtktextbtree.h
gtk/gtktextbuffer.c
gtk/gtktextbuffer.h
gtk/gtktextdisplay.c
gtk/gtktextiter.c
gtk/gtktextiter.h
gtk/gtktextiterprivate.h
gtk/gtktextlayout.c
gtk/gtktextlayout.h
gtk/gtktextmark.c
gtk/gtktextmark.h
gtk/gtktextmarkprivate.h
gtk/gtktextsegment.c
gtk/gtktexttag.c
gtk/gtktexttag.h
gtk/gtktexttagprivate.h
gtk/gtktexttagtable.c
gtk/gtktexttagtable.h
gtk/gtktexttypes.c
gtk/gtktexttypes.h
gtk/gtktextview.c
gtk/gtktextview.h
gtk/testtext.c
gtk/testtextbuffer.c
tests/testtext.c
tests/testtextbuffer.c

index 5691db40552d1d56af3841ec684a7acc7028b78b..514f95820ea9774b87288c8504b641055701ddb4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,97 @@
+2000-07-25  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/testtext.c, gtk/testtextbuffer.c: update to reflect text
+       widget changes.
+
+       * gtk/gtktextview.h: To be consistent with usage of "line"
+       throughout the API to mean "newline-terminated thingy", change
+       MOVEMENT_LINE to be MOVEMENT_WRAPPED_LINE, and MOVEMENT_PARAGRAPH
+       to MOVEMENT_LINE.
+
+       (GtkTextView): Add flags for default editability, and whether to
+       show the cursor. Add functions to get/set that. Add 
+
+       (gtk_text_view_get_iter_location): new function
+
+       * gtk/gtktexttypes.h: Move GtkTextLine typedef from here to
+       gtktextlayout.h
+       (g_convert): Add g_convert temporarily, will go in glib in a bit
+       
+       * gtk/gtktexttagtable.h: include gtktexttag.h, and define
+       GtkTextTagTableForeach instead of brokenly using GHFunc.
+       Change gtk_text_tag_table_foreach() so it doesn't use GHFunc.
+
+       * gtk/gtktexttagprivate.h: Remove GtkTextStyleValues from here,
+       moved to public header.
+
+       * gtk/gtktexttag.h: Rename the "elide" attribute of tags to
+       "invisible", since "elide" was a bad name.
+       (gtk_text_tag_get_priority): Added
+
+       (GtkTextStyleValues): put this in public header, along with
+       functions to use it.
+
+       * gtk/gtktextmarkprivate.h: Include more headers, since we no
+       longer include gtktextbtree.h.
+
+       * gtk/gtktextmark.h: Add gtk_text_mark_ref, gtk_text_mark_unref,
+       gtk_text_mark_deleted
+
+       * gtk/gtktextlayout.h: Don't include the "really private" headers,
+       only buffer/iter. Forward declare GtkTextLIne and GtkTextLineData
+       to make this possible. Now we only need to install
+       gtktextlayout.h, not gtktextbtree.h and gtktext*private.h.
+       (However the Makefile.am isn't changed yet because of the
+       logistics of merging gtk-hp-patches piecemeal)
+
+       * gtk/gtktextiterprivate.h: include btree header, so it compiles;
+       rename gtk_text_iter_get_line to gtk_text_iter_get_text_line since
+       gtk_text_iter_get_line is now used in the public API for a
+       different purpose.
+
+       * gtk/gtktextiter.h: Clean up function names to be more
+       consistent. Always call char offset "offset" and byte index
+       "index". A "line" is always a line number. 
+
+       (gtk_text_iter_is_last): new function, more efficient than 
+       the existing way to check
+       (gtk_text_iter_is_first): new function, also more efficient
+
+       (gtk_text_iter_up_lines, gtk_text_iter_down_lines): Remove these
+
+       (gtk_text_iter_next_char, gtk_text_iter_prev_char): Renamed from 
+       gtk_text_iter_forward_char, etc.
+
+       (gtk_text_iter_forward_to_tag_toggle): Renamed from
+       forward_find_tag_toggle, since this isn't a linear search
+
+       (GtkTextCharPredicate): rename from GtkTextViewCharPredicate
+
+       (gtk_text_iter_forward_search, gtk_text_iter_backward_search): 
+       New functions, search for a buffer substring.
+
+       * gtk/gtktextbuffer.h: Add fields to store whether a paste is
+       interactive and default editable (since we need to store that info
+       until we receive the selection data).
+
+       Remove all the _at_char and at_line etc. versions of functions;
+       only have iterator versions.
+
+       Add _interactive() versions of functions, that consider the
+       editability of text. (FIXME add interactive flag to the 
+       insert/delete signals per Darin's suggestion)
+
+       (gtk_text_buffer_get_tag_table): new function, demand-creates the
+       tag table if necessary
+
+       Remove declaration of gtk_text_buffer_get_iter_from_string
+
+       (_gtk_text_buffer_get_btree): private/internal function, added.
+       
+
+       * gtk/gtktextbtree.h: Remove forward decl of GtkTextLineData.
+       (gtk_text_line_is_last): new function
+
 2000-07-25  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtkprogressbar.h: Implement new sane, 5-function API for
index 5691db40552d1d56af3841ec684a7acc7028b78b..514f95820ea9774b87288c8504b641055701ddb4 100644 (file)
@@ -1,3 +1,97 @@
+2000-07-25  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/testtext.c, gtk/testtextbuffer.c: update to reflect text
+       widget changes.
+
+       * gtk/gtktextview.h: To be consistent with usage of "line"
+       throughout the API to mean "newline-terminated thingy", change
+       MOVEMENT_LINE to be MOVEMENT_WRAPPED_LINE, and MOVEMENT_PARAGRAPH
+       to MOVEMENT_LINE.
+
+       (GtkTextView): Add flags for default editability, and whether to
+       show the cursor. Add functions to get/set that. Add 
+
+       (gtk_text_view_get_iter_location): new function
+
+       * gtk/gtktexttypes.h: Move GtkTextLine typedef from here to
+       gtktextlayout.h
+       (g_convert): Add g_convert temporarily, will go in glib in a bit
+       
+       * gtk/gtktexttagtable.h: include gtktexttag.h, and define
+       GtkTextTagTableForeach instead of brokenly using GHFunc.
+       Change gtk_text_tag_table_foreach() so it doesn't use GHFunc.
+
+       * gtk/gtktexttagprivate.h: Remove GtkTextStyleValues from here,
+       moved to public header.
+
+       * gtk/gtktexttag.h: Rename the "elide" attribute of tags to
+       "invisible", since "elide" was a bad name.
+       (gtk_text_tag_get_priority): Added
+
+       (GtkTextStyleValues): put this in public header, along with
+       functions to use it.
+
+       * gtk/gtktextmarkprivate.h: Include more headers, since we no
+       longer include gtktextbtree.h.
+
+       * gtk/gtktextmark.h: Add gtk_text_mark_ref, gtk_text_mark_unref,
+       gtk_text_mark_deleted
+
+       * gtk/gtktextlayout.h: Don't include the "really private" headers,
+       only buffer/iter. Forward declare GtkTextLIne and GtkTextLineData
+       to make this possible. Now we only need to install
+       gtktextlayout.h, not gtktextbtree.h and gtktext*private.h.
+       (However the Makefile.am isn't changed yet because of the
+       logistics of merging gtk-hp-patches piecemeal)
+
+       * gtk/gtktextiterprivate.h: include btree header, so it compiles;
+       rename gtk_text_iter_get_line to gtk_text_iter_get_text_line since
+       gtk_text_iter_get_line is now used in the public API for a
+       different purpose.
+
+       * gtk/gtktextiter.h: Clean up function names to be more
+       consistent. Always call char offset "offset" and byte index
+       "index". A "line" is always a line number. 
+
+       (gtk_text_iter_is_last): new function, more efficient than 
+       the existing way to check
+       (gtk_text_iter_is_first): new function, also more efficient
+
+       (gtk_text_iter_up_lines, gtk_text_iter_down_lines): Remove these
+
+       (gtk_text_iter_next_char, gtk_text_iter_prev_char): Renamed from 
+       gtk_text_iter_forward_char, etc.
+
+       (gtk_text_iter_forward_to_tag_toggle): Renamed from
+       forward_find_tag_toggle, since this isn't a linear search
+
+       (GtkTextCharPredicate): rename from GtkTextViewCharPredicate
+
+       (gtk_text_iter_forward_search, gtk_text_iter_backward_search): 
+       New functions, search for a buffer substring.
+
+       * gtk/gtktextbuffer.h: Add fields to store whether a paste is
+       interactive and default editable (since we need to store that info
+       until we receive the selection data).
+
+       Remove all the _at_char and at_line etc. versions of functions;
+       only have iterator versions.
+
+       Add _interactive() versions of functions, that consider the
+       editability of text. (FIXME add interactive flag to the 
+       insert/delete signals per Darin's suggestion)
+
+       (gtk_text_buffer_get_tag_table): new function, demand-creates the
+       tag table if necessary
+
+       Remove declaration of gtk_text_buffer_get_iter_from_string
+
+       (_gtk_text_buffer_get_btree): private/internal function, added.
+       
+
+       * gtk/gtktextbtree.h: Remove forward decl of GtkTextLineData.
+       (gtk_text_line_is_last): new function
+
 2000-07-25  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtkprogressbar.h: Implement new sane, 5-function API for
index 5691db40552d1d56af3841ec684a7acc7028b78b..514f95820ea9774b87288c8504b641055701ddb4 100644 (file)
@@ -1,3 +1,97 @@
+2000-07-25  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/testtext.c, gtk/testtextbuffer.c: update to reflect text
+       widget changes.
+
+       * gtk/gtktextview.h: To be consistent with usage of "line"
+       throughout the API to mean "newline-terminated thingy", change
+       MOVEMENT_LINE to be MOVEMENT_WRAPPED_LINE, and MOVEMENT_PARAGRAPH
+       to MOVEMENT_LINE.
+
+       (GtkTextView): Add flags for default editability, and whether to
+       show the cursor. Add functions to get/set that. Add 
+
+       (gtk_text_view_get_iter_location): new function
+
+       * gtk/gtktexttypes.h: Move GtkTextLine typedef from here to
+       gtktextlayout.h
+       (g_convert): Add g_convert temporarily, will go in glib in a bit
+       
+       * gtk/gtktexttagtable.h: include gtktexttag.h, and define
+       GtkTextTagTableForeach instead of brokenly using GHFunc.
+       Change gtk_text_tag_table_foreach() so it doesn't use GHFunc.
+
+       * gtk/gtktexttagprivate.h: Remove GtkTextStyleValues from here,
+       moved to public header.
+
+       * gtk/gtktexttag.h: Rename the "elide" attribute of tags to
+       "invisible", since "elide" was a bad name.
+       (gtk_text_tag_get_priority): Added
+
+       (GtkTextStyleValues): put this in public header, along with
+       functions to use it.
+
+       * gtk/gtktextmarkprivate.h: Include more headers, since we no
+       longer include gtktextbtree.h.
+
+       * gtk/gtktextmark.h: Add gtk_text_mark_ref, gtk_text_mark_unref,
+       gtk_text_mark_deleted
+
+       * gtk/gtktextlayout.h: Don't include the "really private" headers,
+       only buffer/iter. Forward declare GtkTextLIne and GtkTextLineData
+       to make this possible. Now we only need to install
+       gtktextlayout.h, not gtktextbtree.h and gtktext*private.h.
+       (However the Makefile.am isn't changed yet because of the
+       logistics of merging gtk-hp-patches piecemeal)
+
+       * gtk/gtktextiterprivate.h: include btree header, so it compiles;
+       rename gtk_text_iter_get_line to gtk_text_iter_get_text_line since
+       gtk_text_iter_get_line is now used in the public API for a
+       different purpose.
+
+       * gtk/gtktextiter.h: Clean up function names to be more
+       consistent. Always call char offset "offset" and byte index
+       "index". A "line" is always a line number. 
+
+       (gtk_text_iter_is_last): new function, more efficient than 
+       the existing way to check
+       (gtk_text_iter_is_first): new function, also more efficient
+
+       (gtk_text_iter_up_lines, gtk_text_iter_down_lines): Remove these
+
+       (gtk_text_iter_next_char, gtk_text_iter_prev_char): Renamed from 
+       gtk_text_iter_forward_char, etc.
+
+       (gtk_text_iter_forward_to_tag_toggle): Renamed from
+       forward_find_tag_toggle, since this isn't a linear search
+
+       (GtkTextCharPredicate): rename from GtkTextViewCharPredicate
+
+       (gtk_text_iter_forward_search, gtk_text_iter_backward_search): 
+       New functions, search for a buffer substring.
+
+       * gtk/gtktextbuffer.h: Add fields to store whether a paste is
+       interactive and default editable (since we need to store that info
+       until we receive the selection data).
+
+       Remove all the _at_char and at_line etc. versions of functions;
+       only have iterator versions.
+
+       Add _interactive() versions of functions, that consider the
+       editability of text. (FIXME add interactive flag to the 
+       insert/delete signals per Darin's suggestion)
+
+       (gtk_text_buffer_get_tag_table): new function, demand-creates the
+       tag table if necessary
+
+       Remove declaration of gtk_text_buffer_get_iter_from_string
+
+       (_gtk_text_buffer_get_btree): private/internal function, added.
+       
+
+       * gtk/gtktextbtree.h: Remove forward decl of GtkTextLineData.
+       (gtk_text_line_is_last): new function
+
 2000-07-25  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtkprogressbar.h: Implement new sane, 5-function API for
index 5691db40552d1d56af3841ec684a7acc7028b78b..514f95820ea9774b87288c8504b641055701ddb4 100644 (file)
@@ -1,3 +1,97 @@
+2000-07-25  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/testtext.c, gtk/testtextbuffer.c: update to reflect text
+       widget changes.
+
+       * gtk/gtktextview.h: To be consistent with usage of "line"
+       throughout the API to mean "newline-terminated thingy", change
+       MOVEMENT_LINE to be MOVEMENT_WRAPPED_LINE, and MOVEMENT_PARAGRAPH
+       to MOVEMENT_LINE.
+
+       (GtkTextView): Add flags for default editability, and whether to
+       show the cursor. Add functions to get/set that. Add 
+
+       (gtk_text_view_get_iter_location): new function
+
+       * gtk/gtktexttypes.h: Move GtkTextLine typedef from here to
+       gtktextlayout.h
+       (g_convert): Add g_convert temporarily, will go in glib in a bit
+       
+       * gtk/gtktexttagtable.h: include gtktexttag.h, and define
+       GtkTextTagTableForeach instead of brokenly using GHFunc.
+       Change gtk_text_tag_table_foreach() so it doesn't use GHFunc.
+
+       * gtk/gtktexttagprivate.h: Remove GtkTextStyleValues from here,
+       moved to public header.
+
+       * gtk/gtktexttag.h: Rename the "elide" attribute of tags to
+       "invisible", since "elide" was a bad name.
+       (gtk_text_tag_get_priority): Added
+
+       (GtkTextStyleValues): put this in public header, along with
+       functions to use it.
+
+       * gtk/gtktextmarkprivate.h: Include more headers, since we no
+       longer include gtktextbtree.h.
+
+       * gtk/gtktextmark.h: Add gtk_text_mark_ref, gtk_text_mark_unref,
+       gtk_text_mark_deleted
+
+       * gtk/gtktextlayout.h: Don't include the "really private" headers,
+       only buffer/iter. Forward declare GtkTextLIne and GtkTextLineData
+       to make this possible. Now we only need to install
+       gtktextlayout.h, not gtktextbtree.h and gtktext*private.h.
+       (However the Makefile.am isn't changed yet because of the
+       logistics of merging gtk-hp-patches piecemeal)
+
+       * gtk/gtktextiterprivate.h: include btree header, so it compiles;
+       rename gtk_text_iter_get_line to gtk_text_iter_get_text_line since
+       gtk_text_iter_get_line is now used in the public API for a
+       different purpose.
+
+       * gtk/gtktextiter.h: Clean up function names to be more
+       consistent. Always call char offset "offset" and byte index
+       "index". A "line" is always a line number. 
+
+       (gtk_text_iter_is_last): new function, more efficient than 
+       the existing way to check
+       (gtk_text_iter_is_first): new function, also more efficient
+
+       (gtk_text_iter_up_lines, gtk_text_iter_down_lines): Remove these
+
+       (gtk_text_iter_next_char, gtk_text_iter_prev_char): Renamed from 
+       gtk_text_iter_forward_char, etc.
+
+       (gtk_text_iter_forward_to_tag_toggle): Renamed from
+       forward_find_tag_toggle, since this isn't a linear search
+
+       (GtkTextCharPredicate): rename from GtkTextViewCharPredicate
+
+       (gtk_text_iter_forward_search, gtk_text_iter_backward_search): 
+       New functions, search for a buffer substring.
+
+       * gtk/gtktextbuffer.h: Add fields to store whether a paste is
+       interactive and default editable (since we need to store that info
+       until we receive the selection data).
+
+       Remove all the _at_char and at_line etc. versions of functions;
+       only have iterator versions.
+
+       Add _interactive() versions of functions, that consider the
+       editability of text. (FIXME add interactive flag to the 
+       insert/delete signals per Darin's suggestion)
+
+       (gtk_text_buffer_get_tag_table): new function, demand-creates the
+       tag table if necessary
+
+       Remove declaration of gtk_text_buffer_get_iter_from_string
+
+       (_gtk_text_buffer_get_btree): private/internal function, added.
+       
+
+       * gtk/gtktextbtree.h: Remove forward decl of GtkTextLineData.
+       (gtk_text_line_is_last): new function
+
 2000-07-25  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtkprogressbar.h: Implement new sane, 5-function API for
index 5691db40552d1d56af3841ec684a7acc7028b78b..514f95820ea9774b87288c8504b641055701ddb4 100644 (file)
@@ -1,3 +1,97 @@
+2000-07-25  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/testtext.c, gtk/testtextbuffer.c: update to reflect text
+       widget changes.
+
+       * gtk/gtktextview.h: To be consistent with usage of "line"
+       throughout the API to mean "newline-terminated thingy", change
+       MOVEMENT_LINE to be MOVEMENT_WRAPPED_LINE, and MOVEMENT_PARAGRAPH
+       to MOVEMENT_LINE.
+
+       (GtkTextView): Add flags for default editability, and whether to
+       show the cursor. Add functions to get/set that. Add 
+
+       (gtk_text_view_get_iter_location): new function
+
+       * gtk/gtktexttypes.h: Move GtkTextLine typedef from here to
+       gtktextlayout.h
+       (g_convert): Add g_convert temporarily, will go in glib in a bit
+       
+       * gtk/gtktexttagtable.h: include gtktexttag.h, and define
+       GtkTextTagTableForeach instead of brokenly using GHFunc.
+       Change gtk_text_tag_table_foreach() so it doesn't use GHFunc.
+
+       * gtk/gtktexttagprivate.h: Remove GtkTextStyleValues from here,
+       moved to public header.
+
+       * gtk/gtktexttag.h: Rename the "elide" attribute of tags to
+       "invisible", since "elide" was a bad name.
+       (gtk_text_tag_get_priority): Added
+
+       (GtkTextStyleValues): put this in public header, along with
+       functions to use it.
+
+       * gtk/gtktextmarkprivate.h: Include more headers, since we no
+       longer include gtktextbtree.h.
+
+       * gtk/gtktextmark.h: Add gtk_text_mark_ref, gtk_text_mark_unref,
+       gtk_text_mark_deleted
+
+       * gtk/gtktextlayout.h: Don't include the "really private" headers,
+       only buffer/iter. Forward declare GtkTextLIne and GtkTextLineData
+       to make this possible. Now we only need to install
+       gtktextlayout.h, not gtktextbtree.h and gtktext*private.h.
+       (However the Makefile.am isn't changed yet because of the
+       logistics of merging gtk-hp-patches piecemeal)
+
+       * gtk/gtktextiterprivate.h: include btree header, so it compiles;
+       rename gtk_text_iter_get_line to gtk_text_iter_get_text_line since
+       gtk_text_iter_get_line is now used in the public API for a
+       different purpose.
+
+       * gtk/gtktextiter.h: Clean up function names to be more
+       consistent. Always call char offset "offset" and byte index
+       "index". A "line" is always a line number. 
+
+       (gtk_text_iter_is_last): new function, more efficient than 
+       the existing way to check
+       (gtk_text_iter_is_first): new function, also more efficient
+
+       (gtk_text_iter_up_lines, gtk_text_iter_down_lines): Remove these
+
+       (gtk_text_iter_next_char, gtk_text_iter_prev_char): Renamed from 
+       gtk_text_iter_forward_char, etc.
+
+       (gtk_text_iter_forward_to_tag_toggle): Renamed from
+       forward_find_tag_toggle, since this isn't a linear search
+
+       (GtkTextCharPredicate): rename from GtkTextViewCharPredicate
+
+       (gtk_text_iter_forward_search, gtk_text_iter_backward_search): 
+       New functions, search for a buffer substring.
+
+       * gtk/gtktextbuffer.h: Add fields to store whether a paste is
+       interactive and default editable (since we need to store that info
+       until we receive the selection data).
+
+       Remove all the _at_char and at_line etc. versions of functions;
+       only have iterator versions.
+
+       Add _interactive() versions of functions, that consider the
+       editability of text. (FIXME add interactive flag to the 
+       insert/delete signals per Darin's suggestion)
+
+       (gtk_text_buffer_get_tag_table): new function, demand-creates the
+       tag table if necessary
+
+       Remove declaration of gtk_text_buffer_get_iter_from_string
+
+       (_gtk_text_buffer_get_btree): private/internal function, added.
+       
+
+       * gtk/gtktextbtree.h: Remove forward decl of GtkTextLineData.
+       (gtk_text_line_is_last): new function
+
 2000-07-25  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtkprogressbar.h: Implement new sane, 5-function API for
index 5691db40552d1d56af3841ec684a7acc7028b78b..514f95820ea9774b87288c8504b641055701ddb4 100644 (file)
@@ -1,3 +1,97 @@
+2000-07-25  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/testtext.c, gtk/testtextbuffer.c: update to reflect text
+       widget changes.
+
+       * gtk/gtktextview.h: To be consistent with usage of "line"
+       throughout the API to mean "newline-terminated thingy", change
+       MOVEMENT_LINE to be MOVEMENT_WRAPPED_LINE, and MOVEMENT_PARAGRAPH
+       to MOVEMENT_LINE.
+
+       (GtkTextView): Add flags for default editability, and whether to
+       show the cursor. Add functions to get/set that. Add 
+
+       (gtk_text_view_get_iter_location): new function
+
+       * gtk/gtktexttypes.h: Move GtkTextLine typedef from here to
+       gtktextlayout.h
+       (g_convert): Add g_convert temporarily, will go in glib in a bit
+       
+       * gtk/gtktexttagtable.h: include gtktexttag.h, and define
+       GtkTextTagTableForeach instead of brokenly using GHFunc.
+       Change gtk_text_tag_table_foreach() so it doesn't use GHFunc.
+
+       * gtk/gtktexttagprivate.h: Remove GtkTextStyleValues from here,
+       moved to public header.
+
+       * gtk/gtktexttag.h: Rename the "elide" attribute of tags to
+       "invisible", since "elide" was a bad name.
+       (gtk_text_tag_get_priority): Added
+
+       (GtkTextStyleValues): put this in public header, along with
+       functions to use it.
+
+       * gtk/gtktextmarkprivate.h: Include more headers, since we no
+       longer include gtktextbtree.h.
+
+       * gtk/gtktextmark.h: Add gtk_text_mark_ref, gtk_text_mark_unref,
+       gtk_text_mark_deleted
+
+       * gtk/gtktextlayout.h: Don't include the "really private" headers,
+       only buffer/iter. Forward declare GtkTextLIne and GtkTextLineData
+       to make this possible. Now we only need to install
+       gtktextlayout.h, not gtktextbtree.h and gtktext*private.h.
+       (However the Makefile.am isn't changed yet because of the
+       logistics of merging gtk-hp-patches piecemeal)
+
+       * gtk/gtktextiterprivate.h: include btree header, so it compiles;
+       rename gtk_text_iter_get_line to gtk_text_iter_get_text_line since
+       gtk_text_iter_get_line is now used in the public API for a
+       different purpose.
+
+       * gtk/gtktextiter.h: Clean up function names to be more
+       consistent. Always call char offset "offset" and byte index
+       "index". A "line" is always a line number. 
+
+       (gtk_text_iter_is_last): new function, more efficient than 
+       the existing way to check
+       (gtk_text_iter_is_first): new function, also more efficient
+
+       (gtk_text_iter_up_lines, gtk_text_iter_down_lines): Remove these
+
+       (gtk_text_iter_next_char, gtk_text_iter_prev_char): Renamed from 
+       gtk_text_iter_forward_char, etc.
+
+       (gtk_text_iter_forward_to_tag_toggle): Renamed from
+       forward_find_tag_toggle, since this isn't a linear search
+
+       (GtkTextCharPredicate): rename from GtkTextViewCharPredicate
+
+       (gtk_text_iter_forward_search, gtk_text_iter_backward_search): 
+       New functions, search for a buffer substring.
+
+       * gtk/gtktextbuffer.h: Add fields to store whether a paste is
+       interactive and default editable (since we need to store that info
+       until we receive the selection data).
+
+       Remove all the _at_char and at_line etc. versions of functions;
+       only have iterator versions.
+
+       Add _interactive() versions of functions, that consider the
+       editability of text. (FIXME add interactive flag to the 
+       insert/delete signals per Darin's suggestion)
+
+       (gtk_text_buffer_get_tag_table): new function, demand-creates the
+       tag table if necessary
+
+       Remove declaration of gtk_text_buffer_get_iter_from_string
+
+       (_gtk_text_buffer_get_btree): private/internal function, added.
+       
+
+       * gtk/gtktextbtree.h: Remove forward decl of GtkTextLineData.
+       (gtk_text_line_is_last): new function
+
 2000-07-25  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtkprogressbar.h: Implement new sane, 5-function API for
index 5691db40552d1d56af3841ec684a7acc7028b78b..514f95820ea9774b87288c8504b641055701ddb4 100644 (file)
@@ -1,3 +1,97 @@
+2000-07-25  Havoc Pennington  <hp@redhat.com>
+
+       * gtk/testtext.c, gtk/testtextbuffer.c: update to reflect text
+       widget changes.
+
+       * gtk/gtktextview.h: To be consistent with usage of "line"
+       throughout the API to mean "newline-terminated thingy", change
+       MOVEMENT_LINE to be MOVEMENT_WRAPPED_LINE, and MOVEMENT_PARAGRAPH
+       to MOVEMENT_LINE.
+
+       (GtkTextView): Add flags for default editability, and whether to
+       show the cursor. Add functions to get/set that. Add 
+
+       (gtk_text_view_get_iter_location): new function
+
+       * gtk/gtktexttypes.h: Move GtkTextLine typedef from here to
+       gtktextlayout.h
+       (g_convert): Add g_convert temporarily, will go in glib in a bit
+       
+       * gtk/gtktexttagtable.h: include gtktexttag.h, and define
+       GtkTextTagTableForeach instead of brokenly using GHFunc.
+       Change gtk_text_tag_table_foreach() so it doesn't use GHFunc.
+
+       * gtk/gtktexttagprivate.h: Remove GtkTextStyleValues from here,
+       moved to public header.
+
+       * gtk/gtktexttag.h: Rename the "elide" attribute of tags to
+       "invisible", since "elide" was a bad name.
+       (gtk_text_tag_get_priority): Added
+
+       (GtkTextStyleValues): put this in public header, along with
+       functions to use it.
+
+       * gtk/gtktextmarkprivate.h: Include more headers, since we no
+       longer include gtktextbtree.h.
+
+       * gtk/gtktextmark.h: Add gtk_text_mark_ref, gtk_text_mark_unref,
+       gtk_text_mark_deleted
+
+       * gtk/gtktextlayout.h: Don't include the "really private" headers,
+       only buffer/iter. Forward declare GtkTextLIne and GtkTextLineData
+       to make this possible. Now we only need to install
+       gtktextlayout.h, not gtktextbtree.h and gtktext*private.h.
+       (However the Makefile.am isn't changed yet because of the
+       logistics of merging gtk-hp-patches piecemeal)
+
+       * gtk/gtktextiterprivate.h: include btree header, so it compiles;
+       rename gtk_text_iter_get_line to gtk_text_iter_get_text_line since
+       gtk_text_iter_get_line is now used in the public API for a
+       different purpose.
+
+       * gtk/gtktextiter.h: Clean up function names to be more
+       consistent. Always call char offset "offset" and byte index
+       "index". A "line" is always a line number. 
+
+       (gtk_text_iter_is_last): new function, more efficient than 
+       the existing way to check
+       (gtk_text_iter_is_first): new function, also more efficient
+
+       (gtk_text_iter_up_lines, gtk_text_iter_down_lines): Remove these
+
+       (gtk_text_iter_next_char, gtk_text_iter_prev_char): Renamed from 
+       gtk_text_iter_forward_char, etc.
+
+       (gtk_text_iter_forward_to_tag_toggle): Renamed from
+       forward_find_tag_toggle, since this isn't a linear search
+
+       (GtkTextCharPredicate): rename from GtkTextViewCharPredicate
+
+       (gtk_text_iter_forward_search, gtk_text_iter_backward_search): 
+       New functions, search for a buffer substring.
+
+       * gtk/gtktextbuffer.h: Add fields to store whether a paste is
+       interactive and default editable (since we need to store that info
+       until we receive the selection data).
+
+       Remove all the _at_char and at_line etc. versions of functions;
+       only have iterator versions.
+
+       Add _interactive() versions of functions, that consider the
+       editability of text. (FIXME add interactive flag to the 
+       insert/delete signals per Darin's suggestion)
+
+       (gtk_text_buffer_get_tag_table): new function, demand-creates the
+       tag table if necessary
+
+       Remove declaration of gtk_text_buffer_get_iter_from_string
+
+       (_gtk_text_buffer_get_btree): private/internal function, added.
+       
+
+       * gtk/gtktextbtree.h: Remove forward decl of GtkTextLineData.
+       (gtk_text_line_is_last): new function
+
 2000-07-25  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtkprogressbar.h: Implement new sane, 5-function API for
index 8c2b3e00afb1270a1fe4525da23e7965365cfaed..e51f2bbd08b6a5d24b0e425da1ea13507347b72f 100644 (file)
@@ -567,8 +567,8 @@ gtk_text_btree_delete (GtkTextIter *start,
     gint line1;
     gint line2;
     
-    line1 = gtk_text_iter_get_line_number(start);
-    line2 = gtk_text_iter_get_line_number(end);
+    line1 = gtk_text_iter_get_line(start);
+    line2 = gtk_text_iter_get_line(end);
     
     if (line2 == gtk_text_btree_line_count(tree))
       {
@@ -577,14 +577,14 @@ gtk_text_btree_delete (GtkTextIter *start,
         GtkTextIter orig_end;
         
         orig_end = *end;
-        gtk_text_iter_backward_char(end);
+        gtk_text_iter_prev_char(end);
         
         --line2;
 
-        if (gtk_text_iter_get_line_char(start) == 0 &&
+        if (gtk_text_iter_get_line_offset(start) == 0 &&
             line1 != 0)
           {
-            gtk_text_iter_backward_char(start);
+            gtk_text_iter_prev_char(start);
             --line1;
           }
         
@@ -612,10 +612,10 @@ gtk_text_btree_delete (GtkTextIter *start,
   gtk_text_btree_invalidate_region(tree, start, end);
 
   /* Save the byte offset so we can reset the iterators */
-  start_byte_offset = gtk_text_iter_get_line_byte(start);
+  start_byte_offset = gtk_text_iter_get_line_index(start);
   
-  start_line = gtk_text_iter_get_line(start);
-  end_line = gtk_text_iter_get_line(end);
+  start_line = gtk_text_iter_get_text_line(start);
+  end_line = gtk_text_iter_get_text_line(end);
   
   /*
    * Split the start and end segments, so we have a place
@@ -921,9 +921,9 @@ gtk_text_btree_insert (GtkTextIter *iter,
 
   /* extract iterator info */
   tree = gtk_text_iter_get_btree(iter);
-  line = gtk_text_iter_get_line(iter);
+  line = gtk_text_iter_get_text_line(iter);
   start_line = line;
-  start_byte_index = gtk_text_iter_get_line_byte(iter);
+  start_byte_index = gtk_text_iter_get_line_index(iter);
 
   /* Get our insertion segment split */
   prev_seg = gtk_text_line_segment_split(iter);
@@ -1045,9 +1045,9 @@ gtk_text_btree_insert_pixmap (GtkTextIter *iter,
   GtkTextBTree *tree;
   gint start_byte_offset;
   
-  line = gtk_text_iter_get_line(iter);
+  line = gtk_text_iter_get_text_line(iter);
   tree = gtk_text_iter_get_btree(iter);
-  start_byte_offset = gtk_text_iter_get_line_byte(iter);
+  start_byte_offset = gtk_text_iter_get_line_index(iter);
   
   seg = gtk_text_pixmap_segment_new (pixmap, mask);
 
@@ -1073,7 +1073,7 @@ gtk_text_btree_insert_pixmap (GtkTextIter *iter,
   gtk_text_btree_get_iter_at_line(tree, &start, line, start_byte_offset);
 
   *iter = start;
-  gtk_text_iter_forward_char(iter); /* skip forward past the pixmap */
+  gtk_text_iter_next_char(iter); /* skip forward past the pixmap */
 
   gtk_text_btree_invalidate_region(tree, &start, iter);
 }
@@ -1481,8 +1481,8 @@ gtk_text_btree_tag (const GtkTextIter *start_orig,
   printf("%s tag %s from %d to %d\n",
          add ? "Adding" : "Removing",
          tag->name,
-         gtk_text_iter_get_char_index(start_orig),
-         gtk_text_iter_get_char_index(end_orig));
+         gtk_text_buffer_get_offset(start_orig),
+         gtk_text_buffer_get_offset(end_orig));
 #endif
   
   if (gtk_text_iter_equal(start_orig, end_orig))
@@ -1497,8 +1497,8 @@ gtk_text_btree_tag (const GtkTextIter *start_orig,
 
   info = gtk_text_btree_get_tag_info(tree, tag);
   
-  start_line = gtk_text_iter_get_line(&start);
-  end_line = gtk_text_iter_get_line(&end);
+  start_line = gtk_text_iter_get_text_line(&start);
+  end_line = gtk_text_iter_get_text_line(&end);
 
   /* Find all tag toggles in the region; we are going to delete them.
      We need to find them in advance, because
@@ -1507,8 +1507,8 @@ gtk_text_btree_tag (const GtkTextIter *start_orig,
   stack = iter_stack_new();
   iter = start;
   /* We don't want to delete a toggle that's at the start iterator. */
-  gtk_text_iter_forward_char(&iter);
-  while (gtk_text_iter_forward_find_tag_toggle(&iter, tag))
+  gtk_text_iter_next_char(&iter);
+  while (gtk_text_iter_forward_to_tag_toggle(&iter, tag))
     {
       if (gtk_text_iter_compare(&iter, &end) >= 0)
         break;
@@ -1569,7 +1569,7 @@ gtk_text_btree_tag (const GtkTextIter *start_orig,
       GtkTextLineSegment *indexable_seg;
       GtkTextLine *line;
       
-      line = gtk_text_iter_get_line(&iter);
+      line = gtk_text_iter_get_text_line(&iter);
       seg = gtk_text_iter_get_any_segment(&iter);
       indexable_seg = gtk_text_iter_get_indexable_segment(&iter);
 
@@ -1873,9 +1873,9 @@ gtk_text_btree_get_tags (const GtkTextIter *iter,
 
 #define NUM_TAG_INFOS 10
   
-  line = gtk_text_iter_get_line(iter);
+  line = gtk_text_iter_get_text_line(iter);
   tree = gtk_text_iter_get_btree(iter);
-  byte_index = gtk_text_iter_get_line_byte(iter);
+  byte_index = gtk_text_iter_get_line_index(iter);
 
   tagInfo.numTags = 0;
   tagInfo.arraySize = NUM_TAG_INFOS;
@@ -1993,13 +1993,13 @@ copy_segment(GString *string,
       gint copy_bytes = 0;
       gint copy_start = 0;
 
-      /* Don't copy if we're elided; segments are elided/not
+      /* Don't copy if we're invisible; segments are invisible/not
          as a whole, no need to check each char */
       if (!include_hidden &&
           gtk_text_btree_char_is_invisible(start))
         {
           copy = FALSE;
-          /* printf(" <elided>\n"); */
+          /* printf(" <invisible>\n"); */
         }
 
       copy_start = gtk_text_iter_get_segment_byte(start);
@@ -2012,7 +2012,7 @@ copy_segment(GString *string,
           copy_bytes = end_byte - copy_start;
         }
       else
-        copy_bytes = seg->byte_count;
+        copy_bytes = seg->byte_count - copy_start;
 
       g_assert(copy_bytes != 0); /* Due to iter equality check at
                                     front of this function. */
@@ -2085,18 +2085,17 @@ gtk_text_btree_get_text (const GtkTextIter *start_orig,
   iter = start;
   seg = gtk_text_iter_get_indexable_segment(&iter);
   while (seg != end_seg)
-    {          
+    {      
       copy_segment(retval, include_hidden, include_nonchars,
                    &iter, &end);
 
-      if (!gtk_text_iter_forward_indexable_segment(&iter))
-        g_assert_not_reached(); /* must be able to go forward to
-                                   end_seg, if end_seg still exists
-                                   and was in front. */
-
+      gtk_text_iter_forward_indexable_segment(&iter);
+      
       seg = gtk_text_iter_get_indexable_segment(&iter);
     }
 
+  copy_segment(retval, include_hidden, include_nonchars, &iter, &end);
+  
   str = retval->str;
   g_string_free(retval, FALSE);
   return str;
@@ -2137,9 +2136,9 @@ gtk_text_btree_char_is_invisible (const GtkTextIter *iter)
   GtkTextBTree *tree;
   gint byte_index;
   
-  line = gtk_text_iter_get_line(iter);
+  line = gtk_text_iter_get_text_line(iter);
   tree = gtk_text_iter_get_btree(iter);
-  byte_index = gtk_text_iter_get_line_byte(iter);
+  byte_index = gtk_text_iter_get_line_index(iter);
   
   numTags = gtk_text_tag_table_size(tree->table);
     
@@ -2168,7 +2167,7 @@ gtk_text_btree_char_is_invisible (const GtkTextIter *iter)
           || (seg->type == &gtk_text_toggle_off_type))
         {
           tag = seg->body.toggle.info->tag;
-          if (tag->elide_set && tag->values->elide)
+          if (tag->invisible_set && tag->values->invisible)
             {
               tags[tag->priority] = tag;
               tagCnts[tag->priority]++;
@@ -2192,7 +2191,7 @@ gtk_text_btree_char_is_invisible (const GtkTextIter *iter)
               || (seg->type == &gtk_text_toggle_off_type))
             {
               tag = seg->body.toggle.info->tag;
-              if (tag->elide_set && tag->values->elide)
+              if (tag->invisible_set && tag->values->invisible)
                 {
                   tags[tag->priority] = tag;
                   tagCnts[tag->priority]++;
@@ -2221,7 +2220,7 @@ gtk_text_btree_char_is_invisible (const GtkTextIter *iter)
               if (summary->toggle_count & 1)
                 {
                   tag = summary->info->tag;
-                  if (tag->elide_set && tag->values->elide)
+                  if (tag->invisible_set && tag->values->invisible)
                     {
                       tags[tag->priority] = tag;
                       tagCnts[tag->priority] += summary->toggle_count;
@@ -2233,7 +2232,7 @@ gtk_text_btree_char_is_invisible (const GtkTextIter *iter)
 
   /*
    * Now traverse from highest priority to lowest, 
-   * take elided value from first odd count (= on)
+   * take invisible value from first odd count (= on)
    */
 
   for (i = numTags-1; i >=0; i--)
@@ -2243,7 +2242,7 @@ gtk_text_btree_char_is_invisible (const GtkTextIter *iter)
           /* FIXME not sure this should be if 0 */
 #if 0
 #ifndef ALWAYS_SHOW_SELECTION
-          /* who would make the selection elided? */
+          /* who would make the selection invisible? */
           if ((tag == tkxt->seltag)
               && !(tkxt->flags & GOT_FOCUS))
             {
@@ -2251,7 +2250,7 @@ gtk_text_btree_char_is_invisible (const GtkTextIter *iter)
             }
 #endif
 #endif
-          invisible = tags[i]->values->elide;
+          invisible = tags[i]->values->invisible;
           break;
         }
     }
@@ -2285,8 +2284,8 @@ redisplay_region (GtkTextBTree      *tree,
       end = tmp;
     }
   
-  start_line = gtk_text_iter_get_line (start);
-  end_line = gtk_text_iter_get_line (end);
+  start_line = gtk_text_iter_get_text_line (start);
+  end_line = gtk_text_iter_get_text_line (end);
   
   view = tree->views;
   while (view != NULL)
@@ -2322,7 +2321,7 @@ redisplay_mark(GtkTextLineSegment *mark)
                                   (GtkTextMark*)mark);
 
   end = iter;
-  gtk_text_iter_forward_char(&end);
+  gtk_text_iter_next_char(&end);
 
   gtk_text_btree_invalidate_region(mark->body.mark.tree,
                                    &iter, &end);
@@ -2342,9 +2341,9 @@ ensure_not_off_end(GtkTextBTree *tree,
                    GtkTextLineSegment *mark,
                    GtkTextIter *iter)
 {
-  if (gtk_text_iter_get_line_number(iter) ==
+  if (gtk_text_iter_get_line(iter) ==
       gtk_text_btree_line_count(tree))
-    gtk_text_iter_backward_char(iter);
+    gtk_text_iter_prev_char(iter);
 }
 
 static GtkTextLineSegment*
@@ -2411,8 +2410,8 @@ real_set_mark(GtkTextBTree *tree,
          This could hose our iterator... */
       gtk_text_btree_unlink_segment(tree, mark,
                                     mark->body.mark.line);
-      mark->body.mark.line = gtk_text_iter_get_line(&iter);
-      g_assert(mark->body.mark.line == gtk_text_iter_get_line(&iter));
+      mark->body.mark.line = gtk_text_iter_get_text_line(&iter);
+      g_assert(mark->body.mark.line == gtk_text_iter_get_text_line(&iter));
 
       segments_changed(tree); /* make sure the iterator recomputes its
                                  segment */
@@ -2423,7 +2422,7 @@ real_set_mark(GtkTextBTree *tree,
                               left_gravity,
                               name);
 
-      mark->body.mark.line = gtk_text_iter_get_line(&iter);
+      mark->body.mark.line = gtk_text_iter_get_text_line(&iter);
 
       if (mark->body.mark.name)
         g_hash_table_insert(tree->mark_table,
@@ -2532,6 +2531,10 @@ gtk_text_btree_remove_mark (GtkTextBTree *tree,
   if (segment->body.mark.name)
     g_hash_table_remove(tree->mark_table, segment->body.mark.name);
   mark_segment_unref(segment);
+
+  segment->body.mark.tree = NULL;
+  segment->body.mark.line = NULL;
+  
   segments_changed(tree);
 }
 
@@ -2602,7 +2605,8 @@ gtk_text_btree_first_could_contain_tag (GtkTextBTree *tree,
 
       /* We know the tag root has instances of the given
          tag below it */
-      
+
+    continue_outer_loop:
       g_assert(node != NULL);
       while (node->level > 0)
         {
@@ -2611,14 +2615,13 @@ gtk_text_btree_first_could_contain_tag (GtkTextBTree *tree,
           while (node != NULL)
             {
               if (gtk_text_btree_node_has_tag(node, tag))
-                goto done;
+                goto continue_outer_loop;
+              
               node = node->next;
             }
           g_assert(node != NULL);
         }
       
-    done:
-      
       g_assert(node != NULL); /* The tag summaries said some node had
                                  tag toggles... */
       
@@ -2933,6 +2936,23 @@ gtk_text_line_byte_has_tag (GtkTextLine *line,
     return find_toggle_outside_current_line(line, tree, tag);
 }
 
+gboolean
+gtk_text_line_is_last (GtkTextLine *line)
+{
+  GtkTextBTreeNode *node;
+
+  if (line->next != NULL)
+    return FALSE;
+  else
+    {
+      node = line->parent;
+      while (node != NULL && node->next == NULL)
+        node = node->parent;      
+
+      return node == NULL;
+    }
+}
+
 GtkTextLine*
 gtk_text_line_next (GtkTextLine *line)
 {
@@ -3802,6 +3822,7 @@ gtk_text_line_next_could_contain_tag(GtkTextLine *line,
   /* We have to find the first sub-node of this node that contains
      the target tag. */
 
+ continue_outer_loop:
   while (node->level > 0)
     {
       g_assert(node != NULL); /* If this fails, it likely means an
@@ -3812,13 +3833,12 @@ gtk_text_line_next_could_contain_tag(GtkTextLine *line,
       while (node != NULL)
         {
           if (gtk_text_btree_node_has_tag(node, tag))
-            goto done;
+            goto continue_outer_loop;
           node = node->next;
         }
       g_assert(node != NULL);
     }
 
- done:
   g_assert(node != NULL);
   g_assert(node->level == 0);
   
@@ -5649,7 +5669,7 @@ gtk_text_btree_link_segment(GtkTextLineSegment *seg,
   GtkTextLine *line;
   GtkTextBTree *tree;
   
-  line = gtk_text_iter_get_line(iter);
+  line = gtk_text_iter_get_text_line(iter);
   tree = gtk_text_iter_get_btree(iter);
   
   prev = gtk_text_line_segment_split(iter);
@@ -5996,11 +6016,11 @@ gtk_text_btree_node_check_consistency(GtkTextBTreeNode *node)
 }
 
 static void
-listify_foreach(gpointer key, gpointer value, gpointer user_data)
+listify_foreach(GtkTextTag *tag, gpointer user_data)
 {
   GSList** listp = user_data;
 
-  *listp = g_slist_prepend(*listp, value);
+  *listp = g_slist_prepend(*listp, tag);
 }
 
 static GSList*
index 72085302ed82bd96d1f45a8eb1722e145bad6887..aba6d5095ada2a5bb6e44421c28bef26a89421ea 100644 (file)
@@ -162,8 +162,6 @@ GtkTextLine *       gtk_text_btree_last_could_contain_tag  (GtkTextBTree       *
 
 /* Chunk of data associated with a line; views can use this to store
    info at the line. They should "subclass" the header struct here. */
-typedef struct _GtkTextLineData GtkTextLineData;
-
 struct _GtkTextLineData {
   gpointer view_id;
   GtkTextLineData *next;
@@ -200,6 +198,7 @@ gboolean            gtk_text_line_byte_has_tag               (GtkTextLine
                                                               GtkTextBTree        *tree,
                                                               gint                 byte_in_line,
                                                               GtkTextTag          *tag);
+gboolean            gtk_text_line_is_last                    (GtkTextLine *line);
 GtkTextLine *       gtk_text_line_next                       (GtkTextLine         *line);
 GtkTextLine *       gtk_text_line_previous                   (GtkTextLine         *line);
 void                gtk_text_line_add_data                   (GtkTextLine         *line,
index 75af349bf31053911913bf2f130c67abfacb32f1..6612adf882ace0144e23afdf502261bc786c29a3 100644 (file)
@@ -3,12 +3,15 @@
  *  Developed by Havoc Pennington
  */
 
+#include <string.h>
+
 #include "gtkinvisible.h"
 #include "gtkselection.h"
 #include "gtksignal.h"
 #include "gtktextbuffer.h"
 #include "gtktextbtree.h"
 #include "gtktextiterprivate.h"
+#include <string.h>
 
 enum {
   INSERT_TEXT,
@@ -58,6 +61,7 @@ static void gtk_text_buffer_real_remove_tag            (GtkTextBuffer     *buffe
                                                         const GtkTextIter *start_char,
                                                         const GtkTextIter *end_char);
 
+static GtkTextBTree* get_btree (GtkTextBuffer *buffer);
 
 void gtk_marshal_NONE__INT_POINTER_INT (GtkObject  *object,
                                         GtkSignalFunc func,
@@ -110,10 +114,10 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
                     GTK_RUN_LAST,
                     GTK_CLASS_TYPE (object_class),
                     GTK_SIGNAL_OFFSET (GtkTextBufferClass, insert_text),
-                    gtk_marshal_NONE__INT_POINTER_INT,
+                    gtk_marshal_NONE__POINTER_POINTER_INT,
                     GTK_TYPE_NONE,
                     3,
-                    GTK_TYPE_INT,
+                    GTK_TYPE_POINTER,
                     GTK_TYPE_POINTER,
                     GTK_TYPE_INT);
 
@@ -122,11 +126,11 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
                     GTK_RUN_LAST,
                     GTK_CLASS_TYPE (object_class),
                     GTK_SIGNAL_OFFSET (GtkTextBufferClass, delete_text),
-                    gtk_marshal_NONE__INT_INT,
+                    gtk_marshal_NONE__POINTER_POINTER,
                     GTK_TYPE_NONE,
                     2,
-                    GTK_TYPE_INT,
-                    GTK_TYPE_INT);
+                    GTK_TYPE_POINTER,
+                    GTK_TYPE_POINTER);
 
   signals[CHANGED] =
     gtk_signal_new ("changed",
@@ -172,24 +176,24 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
                     GTK_RUN_LAST,
                     GTK_CLASS_TYPE (object_class),
                     GTK_SIGNAL_OFFSET (GtkTextBufferClass, apply_tag),
-                    gtk_marshal_NONE__POINTER_INT_INT,
+                    gtk_marshal_NONE__POINTER_POINTER_POINTER,
                     GTK_TYPE_NONE,
                     3,
                     GTK_TYPE_POINTER,
-                    GTK_TYPE_INT,
-                    GTK_TYPE_INT);
+                    GTK_TYPE_POINTER,
+                    GTK_TYPE_POINTER);
     
   signals[REMOVE_TAG] =
     gtk_signal_new ("remove_tag",
                     GTK_RUN_LAST,
                     GTK_CLASS_TYPE (object_class),
                     GTK_SIGNAL_OFFSET (GtkTextBufferClass, remove_tag),
-                    gtk_marshal_NONE__POINTER_INT_INT,
+                    gtk_marshal_NONE__POINTER_POINTER_POINTER,
                     GTK_TYPE_NONE,
                     3,
                     GTK_TYPE_POINTER,
-                    GTK_TYPE_INT,
-                    GTK_TYPE_INT);
+                    GTK_TYPE_POINTER,
+                    GTK_TYPE_POINTER);
   
   gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
 
@@ -264,23 +268,16 @@ GtkTextBuffer*
 gtk_text_buffer_new (GtkTextTagTable *table)
 {
   GtkTextBuffer *text_buffer;
-
-  /* This is broken, need construct_only argument for the tag table
-     so language bindings can set it.
-  */
   
   text_buffer = GTK_TEXT_BUFFER (gtk_type_new (gtk_text_buffer_get_type ()));
 
   if (table)
-    text_buffer->tag_table = table;
-  else
-    text_buffer->tag_table = gtk_text_tag_table_new();
-
-  gtk_object_ref (GTK_OBJECT(text_buffer->tag_table));
-  gtk_object_sink (GTK_OBJECT(text_buffer->tag_table));
-  
-  text_buffer->tree = gtk_text_btree_new(text_buffer->tag_table,
-                                         text_buffer);  
+    {
+      text_buffer->tag_table = table;
+      
+      gtk_object_ref (GTK_OBJECT(text_buffer->tag_table));
+      gtk_object_sink (GTK_OBJECT(text_buffer->tag_table));
+    } 
   
   return text_buffer;
 }
@@ -295,11 +292,17 @@ gtk_text_buffer_destroy (GtkObject *object)
   gtk_widget_destroy(buffer->selection_widget);
   buffer->selection_widget = NULL;
 
-  gtk_object_unref(GTK_OBJECT(buffer->tag_table));
-  buffer->tag_table = NULL;
-  
-  gtk_text_btree_unref(buffer->tree);
-  buffer->tree = NULL;
+  if (buffer->tag_table)
+    {
+      gtk_object_unref(GTK_OBJECT(buffer->tag_table));
+      buffer->tag_table = NULL;
+    }
+
+  if (buffer->btree)
+    {
+      gtk_text_btree_unref(buffer->btree);
+      buffer->btree = NULL;
+    }
   
   (* parent_class->destroy) (object);
 }
@@ -314,6 +317,44 @@ gtk_text_buffer_finalize (GObject *object)
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
+static GtkTextTagTable*
+get_table (GtkTextBuffer *buffer)
+{
+  if (buffer->tag_table == NULL)
+    {
+      buffer->tag_table = gtk_text_tag_table_new ();
+
+      gtk_object_ref (GTK_OBJECT(buffer->tag_table));
+      gtk_object_sink (GTK_OBJECT(buffer->tag_table));
+    }
+
+  return buffer->tag_table;
+}
+
+static GtkTextBTree*
+get_btree (GtkTextBuffer *buffer)
+{
+  if (buffer->btree == NULL)
+    buffer->btree = gtk_text_btree_new(gtk_text_buffer_get_tag_table (buffer),
+                                       buffer);
+  
+  return buffer->btree;
+}
+
+GtkTextBTree*
+_gtk_text_buffer_get_btree (GtkTextBuffer *buffer)
+{
+  return get_btree (buffer);
+}
+
+GtkTextTagTable*
+gtk_text_buffer_get_tag_table (GtkTextBuffer  *buffer)
+{
+  g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
+
+  return get_table (buffer);
+}
+
 /*
  * Insertion
  */
@@ -384,41 +425,42 @@ gtk_text_buffer_insert_at_cursor (GtkTextBuffer *buffer,
   gtk_text_buffer_insert(buffer, &iter, text, len);
 }
 
-void
-gtk_text_buffer_insert_at_char         (GtkTextBuffer      *buffer,
-                                        gint                 char_pos,
-                                        const gchar         *text,
-                                        gint                 len)
+gboolean
+gtk_text_buffer_insert_interactive(GtkTextBuffer *buffer,
+                                   GtkTextIter   *iter,
+                                   const gchar   *text,
+                                   gint           len,
+                                   gboolean       editable_by_default)
 {
-  GtkTextIter iter;
-
-  g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
-  g_return_if_fail(text != NULL);
+  g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), FALSE);
+  g_return_val_if_fail(text != NULL, FALSE);
   
-  gtk_text_buffer_get_iter_at_char(buffer, &iter, char_pos);
-
-  gtk_text_buffer_insert(buffer, &iter, text, len);
+  if (gtk_text_iter_editable (iter, editable_by_default))
+    {
+      gtk_text_buffer_insert (buffer, iter, text, len);
+      return TRUE;
+    }
+  else
+    return FALSE;
 }
 
-void
-gtk_text_buffer_insert_after_line(GtkTextBuffer *buffer,
-                                  gint after_this_line,
-                                  const gchar *text,
-                                  gint len)
+gboolean
+gtk_text_buffer_insert_interactive_at_cursor (GtkTextBuffer *buffer,
+                                              const gchar   *text,
+                                              gint           len,
+                                              gboolean       default_editable)
 {
-  GtkTextIter line;
-  
-  g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
-  g_return_if_fail(text != NULL);
-  
-  gtk_text_buffer_get_iter_at_line(buffer,
-                                   &line,
-                                   after_this_line);
+  GtkTextIter iter;
 
-  /* Start of the next line */
-  gtk_text_iter_forward_line(&line);
+  g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), FALSE);
+  g_return_val_if_fail(text != NULL, FALSE);
+  
+  gtk_text_buffer_get_iter_at_mark(buffer, &iter,
+                                   gtk_text_buffer_get_mark (buffer,
+                                                             "insert"));
 
-  gtk_text_buffer_insert(buffer, &line, text, len);
+  return gtk_text_buffer_insert_interactive (buffer, &iter, text, len,
+                                             default_editable);
 }
 
 /*
@@ -433,7 +475,7 @@ gtk_text_buffer_real_delete_text(GtkTextBuffer *buffer,
   g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
   g_return_if_fail(start != NULL);
   g_return_if_fail(end != NULL);
-
+  
   gtk_text_btree_delete(start, end);
 
   /* may have deleted the selection... */
@@ -456,6 +498,8 @@ gtk_text_buffer_emit_delete(GtkTextBuffer *buffer,
   if (gtk_text_iter_equal(start, end))
     return;
 
+  gtk_text_iter_reorder (start, end);
+  
   gtk_signal_emit(GTK_OBJECT(buffer),
                   signals[DELETE_TEXT],
                   start, end);
@@ -473,65 +517,110 @@ gtk_text_buffer_delete (GtkTextBuffer *buffer,
   gtk_text_buffer_emit_delete(buffer, start, end);
 }
 
-void
-gtk_text_buffer_delete_chars (GtkTextBuffer      *buffer,
-                              gint                 start_char,
-                              gint                 end_char)
+gboolean
+gtk_text_buffer_delete_interactive (GtkTextBuffer *buffer,
+                                    GtkTextIter   *start_iter,
+                                    GtkTextIter   *end_iter,
+                                    gboolean       default_editable)
 {
-  GtkTextIter start;
-  GtkTextIter end;
+  GtkTextMark *end_mark;
+  GtkTextMark *start_mark;
+  GtkTextIter iter;
+  gboolean current_state;
+  gboolean deleted_stuff = FALSE;
+
+  /* Delete all editable text in the range start_iter, end_iter */
   
-  g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
+  g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), FALSE);
+  g_return_val_if_fail (start_iter != NULL, FALSE);
+  g_return_val_if_fail (end_iter != NULL, FALSE);
 
-  if (start_char == end_char)
-    return;
+  gtk_text_iter_reorder (start_iter, end_iter);
+  
+  start_mark = gtk_text_buffer_create_mark (buffer, NULL, 
+                                            start_iter, TRUE);
+  end_mark = gtk_text_buffer_create_mark (buffer, NULL, 
+                                          end_iter, FALSE);
+  iter = *start_iter;
+  
+  current_state = gtk_text_iter_editable (&iter, default_editable);
+  
+  while (TRUE)
+    {
+      gboolean new_state;
+      gboolean done = FALSE;
+      GtkTextIter end;
 
-  gtk_text_buffer_get_iter_at_char(buffer, &start, start_char);
-  gtk_text_buffer_get_iter_at_char(buffer, &end, end_char);
+      gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
+      
+      gtk_text_buffer_get_iter_at_mark (buffer, &end, end_mark);
+      
+      if (gtk_text_iter_compare (&iter, &end) >= 0)
+        {
+          done = TRUE;
+          iter = end; /* clamp to the last boundary */
+        }
 
-  gtk_text_buffer_emit_delete(buffer, &start, &end);
-}
+      new_state = gtk_text_iter_editable (&iter, default_editable);
 
-void
-gtk_text_buffer_delete_lines(GtkTextBuffer *buffer,
-                             gint start_line,
-                             gint end_line)
-{
-  GtkTextIter start;
-  GtkTextIter end;
-  
-  g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
+      if (current_state == new_state)
+        {
+          if (done)
+            {
+              if (current_state)
+                {
+                  /* We're ending an editable region. Delete said region. */
+                  GtkTextIter start;
+                  
+                  gtk_text_buffer_get_iter_at_mark (buffer, &start, start_mark);
+                  
+                  gtk_text_buffer_delete (buffer, &start, &iter);
+                  
+                  deleted_stuff = TRUE;
+                }
+
+              break;
+            }
+          else
+            continue;
+        }
 
-  if (start_line == end_line)
-    return;
+      if (current_state && !new_state)
+        {
+          /* End of an editable region. Delete it. */
+          GtkTextIter start;
+          
+          gtk_text_buffer_get_iter_at_mark (buffer, &start, start_mark);
+          
+          gtk_text_buffer_delete (buffer, &start, &iter);
 
-  /* start of the start line */
-  gtk_text_buffer_get_iter_at_line(buffer, &start, start_line);
-  
-  /* start of the end line; note that we don't delete the end_line, we
-     want to delete up to the start of it */
-  gtk_text_buffer_get_iter_at_line(buffer, &end, end_line);
-  
-  gtk_text_buffer_delete (buffer, &start, &end);
-}
+          current_state = FALSE;
+          deleted_stuff = TRUE;
+        }
+      else
+        {
+          /* We are at the start of an editable region. We won't be deleting
+           * the previous region. Move start mark to start of this region.
+           */
 
-void
-gtk_text_buffer_delete_from_line(GtkTextBuffer *buffer,
-                                 gint line,
-                                 gint start_char, gint end_char)
-{
-  GtkTextIter start;
-  GtkTextIter end;
-  
-  g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
-  
-  if (start_char == end_char)
-    return;
+          g_assert (!current_state && new_state);          
+          
+          gtk_text_buffer_move_mark (buffer, start_mark,
+                                     &iter);
 
-  gtk_text_buffer_get_iter_at_line_char(buffer, &start, line, start_char);
-  gtk_text_buffer_get_iter_at_line_char(buffer, &end, line, end_char);
 
-  gtk_text_buffer_delete(buffer, &start, &end);
+          current_state = TRUE;
+        }
+
+      if (done)
+        break;
+    }
+
+  
+  gtk_text_buffer_delete_mark (buffer, start_mark);
+  gtk_text_buffer_delete_mark (buffer, end_mark);
+  
+  return deleted_stuff;
 }
 
 /*
@@ -554,49 +643,6 @@ gtk_text_buffer_get_text (GtkTextBuffer      *buffer,
     return gtk_text_iter_get_visible_text(start, end);
 }
 
-gchar*
-gtk_text_buffer_get_text_chars         (GtkTextBuffer      *buffer,
-                                        gint                 start_char,
-                                        gint                 end_char,
-                                        gboolean             include_hidden_chars)
-{
-  GtkTextIter start;
-  GtkTextIter end;
-  
-  g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
-  
-  if (start_char == end_char)
-    return g_strdup("");
-  
-  gtk_text_buffer_get_iter_at_char (buffer, &start, start_char);
-  gtk_text_buffer_get_iter_at_char (buffer, &end, end_char);
-  
-  return gtk_text_buffer_get_text(buffer, &start, &end,
-                                  include_hidden_chars);
-}
-
-gchar*
-gtk_text_buffer_get_text_from_line    (GtkTextBuffer      *buffer,
-                                       gint                 line,
-                                       gint                 start_char,
-                                       gint                 end_char,
-                                       gboolean             include_hidden_chars)
-{
-  GtkTextIter start;
-  GtkTextIter end;
-  
-  g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
-  
-  if (start_char == end_char)
-    return g_strdup("");
-  
-  gtk_text_buffer_get_iter_at_line_char (buffer, &start, line, start_char);
-  gtk_text_buffer_get_iter_at_line_char (buffer, &end, line, end_char);
-  
-  return gtk_text_buffer_get_text(buffer, &start, &end,
-                                  include_hidden_chars);
-}
-
 gchar*
 gtk_text_buffer_get_slice (GtkTextBuffer      *buffer,
                            const GtkTextIter *start,
@@ -613,49 +659,6 @@ gtk_text_buffer_get_slice (GtkTextBuffer      *buffer,
     return gtk_text_iter_get_visible_slice(start, end);
 }
 
-gchar*
-gtk_text_buffer_get_slice_chars         (GtkTextBuffer      *buffer,
-                                         gint                 start_char,
-                                         gint                 end_char,
-                                         gboolean             include_hidden_chars)
-{
-  GtkTextIter start;
-  GtkTextIter end;
-  
-  g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
-  
-  if (start_char == end_char)
-    return g_strdup("");
-  
-  gtk_text_buffer_get_iter_at_char (buffer, &start, start_char);
-  gtk_text_buffer_get_iter_at_char (buffer, &end, end_char);
-  
-  return gtk_text_buffer_get_slice(buffer, &start, &end,
-                                   include_hidden_chars);
-}
-
-gchar*
-gtk_text_buffer_get_slice_from_line    (GtkTextBuffer      *buffer,
-                                        gint                 line,
-                                        gint                 start_char,
-                                        gint                 end_char,
-                                        gboolean             include_hidden_chars)
-{
-  GtkTextIter start;
-  GtkTextIter end;
-  
-  g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
-  
-  if (start_char == end_char)
-    return g_strdup("");
-  
-  gtk_text_buffer_get_iter_at_line_char (buffer, &start, line, start_char);
-  gtk_text_buffer_get_iter_at_line_char (buffer, &end, line, end_char);
-  
-  return gtk_text_buffer_get_slice(buffer, &start, &end,
-                                   include_hidden_chars);
-}
-
 /*
  * Pixmaps
  */
@@ -679,22 +682,6 @@ gtk_text_buffer_insert_pixmap         (GtkTextBuffer      *buffer,
   gtk_text_buffer_set_modified(buffer, TRUE);
 }
 
-void
-gtk_text_buffer_insert_pixmap_at_char (GtkTextBuffer      *buffer,
-                                       gint                 char_pos,
-                                       GdkPixmap           *pixmap,
-                                       GdkBitmap           *mask)
-{
-  GtkTextIter iter;
-
-  g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
-  g_return_if_fail(pixmap != NULL);
-  
-  gtk_text_buffer_get_iter_at_char(buffer, &iter, char_pos);
-
-  gtk_text_buffer_insert_pixmap(buffer, &iter, pixmap, mask);
-}
-
 /*
  * Mark manipulation
  */
@@ -715,7 +702,7 @@ gtk_text_buffer_mark_set (GtkTextBuffer     *buffer,
      to modify the default behavior. */
   gtk_signal_emit(GTK_OBJECT(buffer),
                   signals[MARK_SET],
-                  &location,
+                  location,
                   mark);
 
 }
@@ -745,22 +732,20 @@ gtk_text_buffer_set_mark(GtkTextBuffer *buffer,
   GtkTextIter location;
   GtkTextMark *mark;
   
-  g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
-  
-  mark = gtk_text_btree_set_mark(buffer->tree,
+  mark = gtk_text_btree_set_mark(get_btree (buffer),
                                  existing_mark,
                                  mark_name,
                                  left_gravity,
                                  iter,
                                  should_exist);
 
-  if (gtk_text_btree_mark_is_insert(buffer->tree, mark) ||
-      gtk_text_btree_mark_is_selection_bound(buffer->tree, mark))
+  if (gtk_text_btree_mark_is_insert(get_btree (buffer), mark) ||
+      gtk_text_btree_mark_is_selection_bound(get_btree (buffer), mark))
     {
       gtk_text_buffer_update_primary_selection(buffer);
     }
   
-  gtk_text_btree_get_iter_at_mark(buffer->tree,
+  gtk_text_btree_get_iter_at_mark(get_btree (buffer),
                                   &location,
                                   mark);
   
@@ -775,6 +760,8 @@ gtk_text_buffer_create_mark(GtkTextBuffer *buffer,
                             const GtkTextIter *where,
                             gboolean left_gravity)
 {
+  g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
+  
   return gtk_text_buffer_set_mark(buffer, NULL, mark_name, where,
                                   left_gravity, FALSE);
 }
@@ -785,6 +772,8 @@ gtk_text_buffer_move_mark(GtkTextBuffer *buffer,
                           const GtkTextIter *where)
 {
   g_return_if_fail (mark != NULL);
+  g_return_if_fail (!gtk_text_mark_deleted (mark));
+  g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
   
   gtk_text_buffer_set_mark(buffer, mark, NULL, where, FALSE, TRUE);
 }
@@ -794,9 +783,11 @@ gtk_text_buffer_get_iter_at_mark(GtkTextBuffer *buffer,
                                  GtkTextIter *iter,
                                  GtkTextMark *mark)
 {
+  g_return_if_fail (mark != NULL);
+  g_return_if_fail (!gtk_text_mark_deleted (mark));
   g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
 
-  gtk_text_btree_get_iter_at_mark(buffer->tree,
+  gtk_text_btree_get_iter_at_mark(get_btree (buffer),
                                   iter,
                                   mark);
 }
@@ -805,9 +796,11 @@ void
 gtk_text_buffer_delete_mark(GtkTextBuffer *buffer,
                             GtkTextMark *mark)
 {
+  g_return_if_fail (mark != NULL);
+  g_return_if_fail (!gtk_text_mark_deleted (mark));
   g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
 
-  gtk_text_btree_remove_mark (buffer->tree, mark);
+  gtk_text_btree_remove_mark (get_btree (buffer), mark);
 
   /* See rationale above for MARK_SET on why we emit this after
      removing the mark, rather than removing the mark in a default
@@ -825,7 +818,7 @@ gtk_text_buffer_get_mark (GtkTextBuffer      *buffer,
   g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
   g_return_val_if_fail(name != NULL, NULL);
   
-  mark = gtk_text_btree_get_mark_by_name(buffer->tree, name);
+  mark = gtk_text_btree_get_mark_by_name(get_btree (buffer), name);
 
   return mark;
 }
@@ -834,13 +827,20 @@ void
 gtk_text_buffer_place_cursor (GtkTextBuffer     *buffer,
                               const GtkTextIter *where)
 {
+  GtkTextIter real;
+  
   g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
+
+  real = *where;
+  
+  if (gtk_text_iter_is_last (&real))
+    gtk_text_iter_prev_char (&real);
   
-  gtk_text_btree_place_cursor(buffer->tree, where);
-  gtk_text_buffer_mark_set (buffer, where,
+  gtk_text_btree_place_cursor(get_btree (buffer), &real);
+  gtk_text_buffer_mark_set (buffer, &real,
                             gtk_text_buffer_get_mark (buffer,
                                                       "insert"));
-  gtk_text_buffer_mark_set (buffer, where,
+  gtk_text_buffer_mark_set (buffer, &real,
                             gtk_text_buffer_get_mark (buffer,
                                                       "selection_bound"));
 }
@@ -856,11 +856,10 @@ gtk_text_buffer_create_tag(GtkTextBuffer *buffer,
   GtkTextTag *tag;
   
   g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
-  g_return_val_if_fail(tag_name != NULL, NULL);
   
   tag = gtk_text_tag_new(tag_name);
 
-  gtk_text_tag_table_add(buffer->tag_table, tag);
+  gtk_text_tag_table_add(get_table (buffer), tag);
 
   return tag;
 }
@@ -886,26 +885,12 @@ gtk_text_buffer_real_remove_tag (GtkTextBuffer *buffer,
 
 static void
 gtk_text_buffer_emit_tag(GtkTextBuffer *buffer,
-                         const gchar *name,
+                         GtkTextTag *tag,
                          gboolean apply,
                          const GtkTextIter *start,
                          const GtkTextIter *end)
 {
-  GtkTextTag *tag;
-  
-  g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
-  g_return_if_fail(name != NULL);
-  g_return_if_fail(start != NULL);
-  g_return_if_fail(end != NULL);
-  
-  tag = gtk_text_tag_table_lookup(buffer->tag_table,
-                                  name);
-
-  if (tag == NULL)
-    {
-      g_warning("Unknown tag `%s'", name);
-      return;
-    }
+  g_return_if_fail(tag != NULL);
 
   if (apply)
     gtk_signal_emit(GTK_OBJECT(buffer), signals[APPLY_TAG],
@@ -918,88 +903,122 @@ gtk_text_buffer_emit_tag(GtkTextBuffer *buffer,
 
 void
 gtk_text_buffer_apply_tag(GtkTextBuffer *buffer,
-                          const gchar *name,
+                          GtkTextTag    *tag,
                           const GtkTextIter *start,
                           const GtkTextIter *end)
 {
-  gtk_text_buffer_emit_tag(buffer, name, TRUE, start, end);
+  g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
+  g_return_if_fail(GTK_IS_TEXT_TAG (tag));
+  g_return_if_fail(start != NULL);
+  g_return_if_fail(end != NULL);  
+
+  gtk_text_buffer_emit_tag(buffer, tag, TRUE, start, end);
 }
 
 void
 gtk_text_buffer_remove_tag(GtkTextBuffer *buffer,
-                           const gchar *name,
+                           GtkTextTag    *tag,
                            const GtkTextIter *start,
                            const GtkTextIter *end)
 
 {
-  gtk_text_buffer_emit_tag(buffer, name, FALSE, start, end);
+  g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
+  g_return_if_fail(GTK_IS_TEXT_TAG (tag));
+  g_return_if_fail(start != NULL);
+  g_return_if_fail(end != NULL);
+
+  gtk_text_buffer_emit_tag(buffer, tag, FALSE, start, end);
 }
 
+
 void
-gtk_text_buffer_apply_tag_to_chars(GtkTextBuffer *buffer,
+gtk_text_buffer_apply_tag_by_name (GtkTextBuffer *buffer,
                                    const gchar *name,
-                                   gint start_char, gint end_char)
+                                   const GtkTextIter *start,
+                                   const GtkTextIter *end)
 {
-  GtkTextIter start;
-  GtkTextIter end;
-
-  gtk_text_buffer_get_iter_at_char(buffer, &start, start_char);
-  gtk_text_buffer_get_iter_at_char(buffer, &end, end_char);
+  GtkTextTag *tag;
+  
+  g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
+  g_return_if_fail(name != NULL);
+  g_return_if_fail(start != NULL);
+  g_return_if_fail(end != NULL);
   
-  gtk_text_buffer_apply_tag(buffer, name, &start, &end);
+  tag = gtk_text_tag_table_lookup(get_table (buffer),
+                                  name);
+
+  if (tag == NULL)
+    {
+      g_warning("Unknown tag `%s'", name);
+      return;
+    }
+
+  gtk_text_buffer_emit_tag(buffer, tag, TRUE, start, end);
 }
 
 void
-gtk_text_buffer_remove_tag_from_chars(GtkTextBuffer *buffer,
-                                      const gchar *name,
-                                      gint start_char, gint end_char)
+gtk_text_buffer_remove_tag_by_name (GtkTextBuffer *buffer,
+                                    const gchar *name,
+                                    const GtkTextIter *start,
+                                    const GtkTextIter *end)
 {
-  GtkTextIter start;
-  GtkTextIter end;
+  GtkTextTag *tag;
+  
+  g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
+  g_return_if_fail(name != NULL);
+  g_return_if_fail(start != NULL);
+  g_return_if_fail(end != NULL);
 
-  gtk_text_buffer_get_iter_at_char(buffer, &start, start_char);
-  gtk_text_buffer_get_iter_at_char(buffer, &end, end_char);
+  tag = gtk_text_tag_table_lookup(get_table (buffer),
+                                  name);
+
+  if (tag == NULL)
+    {
+      g_warning("Unknown tag `%s'", name);
+      return;
+    }
   
-  gtk_text_buffer_remove_tag(buffer, name, &start, &end);
+  gtk_text_buffer_emit_tag(buffer, tag, FALSE, start, end);
 }
 
+
 /*
  * Obtain various iterators
  */
 
 void
-gtk_text_buffer_get_iter_at_line_char    (GtkTextBuffer      *buffer,
-                                          GtkTextIter        *iter,
-                                          gint                 line_number,
-                                          gint                 char_number)
+gtk_text_buffer_get_iter_at_line_offset (GtkTextBuffer      *buffer,
+                                         GtkTextIter        *iter,
+                                         gint                line_number,
+                                         gint                char_offset)
 {  
   g_return_if_fail(iter != NULL);
   g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
 
-  gtk_text_btree_get_iter_at_line_char(buffer->tree,
-                                       iter, line_number, char_number);
+  gtk_text_btree_get_iter_at_line_char(get_btree (buffer),
+                                       iter, line_number, char_offset);
 }
 
 void
 gtk_text_buffer_get_iter_at_line    (GtkTextBuffer      *buffer,
                                      GtkTextIter        *iter,
-                                     gint                 line_number)
+                                     gint                line_number)
 {
   g_return_if_fail(iter != NULL);
   g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
 
-  gtk_text_buffer_get_iter_at_line_char(buffer, iter, line_number, 0);
+  gtk_text_buffer_get_iter_at_line_offset (buffer, iter, line_number, 0);
 }
 
 void
-gtk_text_buffer_get_iter_at_char         (GtkTextBuffer      *buffer,
-                                          GtkTextIter        *iter,
-                                          gint                 char_index)
+gtk_text_buffer_get_iter_at_offset         (GtkTextBuffer      *buffer,
+                                            GtkTextIter        *iter,
+                                            gint                char_offset)
 {
   g_return_if_fail(iter != NULL);
   g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
 
-  gtk_text_btree_get_iter_at_char(buffer->tree, iter, char_index);
+  gtk_text_btree_get_iter_at_char(get_btree (buffer), iter, char_offset);
 }
 
 void
@@ -1009,7 +1028,7 @@ gtk_text_buffer_get_last_iter         (GtkTextBuffer      *buffer,
   g_return_if_fail(iter != NULL);
   g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
 
-  gtk_text_btree_get_last_iter(buffer->tree, iter);
+  gtk_text_btree_get_last_iter(get_btree (buffer), iter);
 }
 
 void
@@ -1021,21 +1040,8 @@ gtk_text_buffer_get_bounds (GtkTextBuffer *buffer,
   g_return_if_fail(end != NULL);
   g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
 
-  gtk_text_btree_get_iter_at_char(buffer->tree, start, 0);
-  gtk_text_btree_get_last_iter(buffer->tree, end);
-}
-
-
-gboolean
-gtk_text_buffer_get_iter_from_string(GtkTextBuffer *buffer,
-                                     GtkTextIter *iter,
-                                     const gchar *index_string)
-{
-  g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), FALSE);
-
-  return gtk_text_btree_get_iter_from_string(buffer->tree,
-                                             iter,
-                                             index_string);
+  gtk_text_btree_get_iter_at_char(get_btree (buffer), start, 0);
+  gtk_text_btree_get_last_iter(get_btree (buffer), end);
 }
 
 /*
@@ -1114,7 +1120,7 @@ gtk_text_buffer_get_line_count(GtkTextBuffer *buffer)
 {
   g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), 0);
   
-  return gtk_text_btree_line_count(buffer->tree);
+  return gtk_text_btree_line_count(get_btree (buffer));
 }
 
 gint
@@ -1122,7 +1128,7 @@ gtk_text_buffer_get_char_count(GtkTextBuffer *buffer)
 {
   g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), 0);
 
-  return gtk_text_btree_char_count(buffer->tree);
+  return gtk_text_btree_char_count(get_btree (buffer));
 }
 
 GSList*
@@ -1426,8 +1432,12 @@ selection_received (GtkWidget        *widget,
         
         utf = gtk_text_latin1_to_utf((const gchar*)selection_data->data,
                                      selection_data->length);
-        gtk_text_buffer_insert (buffer, &insert_point,
-                                utf, -1);
+        if (buffer->paste_interactive)
+          gtk_text_buffer_insert_interactive (buffer, &insert_point,
+                                              utf, -1, buffer->paste_default_editable);
+        else
+          gtk_text_buffer_insert (buffer, &insert_point,
+                                  utf, -1);
         g_free(utf);
       }
       break;
@@ -1451,15 +1461,30 @@ selection_received (GtkWidget        *widget,
                                                &list);
        for (i=0; i<count; i++)
           {
-            /* FIXME this is broken, it assumes the CTEXT is latin1
-               when it probably isn't. */
-            gchar *utf;
-
-            utf = gtk_text_latin1_to_utf(list[i], strlen(list[i]));
+            /* list contains stuff in our default encoding */
+            gboolean free_utf = FALSE;
+            gchar *utf = NULL;
+            gchar *charset = NULL;
             
-            gtk_text_buffer_insert(buffer, &insert_point, utf, -1);
-
-            g_free(utf);
+            if (g_get_charset (&charset))
+              {
+                utf = g_convert (list[i], -1,
+                                 "UTF8", charset,
+                                 NULL);
+                free_utf = TRUE;
+              }
+            else
+              utf = list[i];
+
+            if (buffer->paste_interactive)
+              gtk_text_buffer_insert_interactive (buffer, &insert_point,
+                                                  utf, -1, buffer->paste_default_editable);
+            else
+              gtk_text_buffer_insert (buffer, &insert_point,
+                                      utf, -1);
+
+            if (free_utf)
+              g_free(utf);
           }
 
        if (count > 0)
@@ -1546,9 +1571,14 @@ gtk_text_buffer_update_clipboard_selection(GtkTextBuffer *buffer)
 }
 
 static void
-paste(GtkTextBuffer *buffer, GdkAtom selection, guint32 time)
+paste (GtkTextBuffer *buffer, GdkAtom selection, guint32 time,
+       gboolean interactive,
+       gboolean default_editable)
 {
   ensure_handlers(buffer);
+
+  buffer->paste_interactive = interactive;
+  buffer->paste_default_editable = default_editable;
   
   gtk_selection_convert (buffer->selection_widget, selection,
                          utf8_atom, time);
@@ -1557,25 +1587,31 @@ paste(GtkTextBuffer *buffer, GdkAtom selection, guint32 time)
 void
 gtk_text_buffer_paste_primary_selection(GtkTextBuffer      *buffer,
                                         GtkTextIter        *override_location,
-                                        guint32 time)
+                                        guint32 time,
+                                        gboolean interactive,
+                                        gboolean default_editable)
 {
   if (override_location != NULL)
     gtk_text_buffer_create_mark(buffer,
                                 "__paste_point_override",
                                 override_location, FALSE);
   
-  paste(buffer, GDK_SELECTION_PRIMARY, time);
+  paste(buffer, GDK_SELECTION_PRIMARY, time, interactive, default_editable);
 }
 
 void
 gtk_text_buffer_paste_clipboard        (GtkTextBuffer      *buffer,
-                                        guint32              time)
+                                        guint32              time,
+                                        gboolean            interactive,
+                                        gboolean            default_editable)
 {
-  paste(buffer, clipboard_atom, time);
+  paste(buffer, clipboard_atom, time, interactive, default_editable);
 }
 
 gboolean
-gtk_text_buffer_delete_selection (GtkTextBuffer      *buffer)
+gtk_text_buffer_delete_selection (GtkTextBuffer *buffer,
+                                  gboolean interactive,
+                                  gboolean default_editable)
 {
   GtkTextIter start;
   GtkTextIter end;
@@ -1586,7 +1622,11 @@ gtk_text_buffer_delete_selection (GtkTextBuffer      *buffer)
     }
   else
     {
-      gtk_text_buffer_delete(buffer, &start, &end);
+      if (interactive)
+        gtk_text_buffer_delete_interactive (buffer, &start, &end, default_editable);
+      else
+        gtk_text_buffer_delete (buffer, &start, &end);
+      
       gtk_text_buffer_update_primary_selection(buffer);
       return TRUE; /* We deleted stuff */
     }
@@ -1595,7 +1635,9 @@ gtk_text_buffer_delete_selection (GtkTextBuffer      *buffer)
 static void
 cut_or_copy(GtkTextBuffer *buffer,
             guint32 time,
-            gboolean delete_region_after)
+            gboolean delete_region_after,
+            gboolean interactive,
+            gboolean default_editable)
 {
   /* We prefer to cut the selected region between selection_bound and
      insertion point. If that region is empty, then we cut the region
@@ -1629,22 +1671,29 @@ cut_or_copy(GtkTextBuffer *buffer,
       set_clipboard_contents_nocopy(buffer, text);
       
       if (delete_region_after)
-        gtk_text_buffer_delete(buffer, &start, &end);
+        {
+          if (interactive)
+            gtk_text_buffer_delete_interactive (buffer, &start, &end, default_editable);
+          else
+            gtk_text_buffer_delete (buffer, &start, &end);
+        }
     }
 }
 
 void
 gtk_text_buffer_cut (GtkTextBuffer      *buffer,
-                     guint32              time)
+                     guint32              time,
+                     gboolean interactive,
+                     gboolean default_editable)
 {
-  cut_or_copy(buffer, time, TRUE);
+  cut_or_copy(buffer, time, TRUE, interactive, default_editable);
 }
 
 void
 gtk_text_buffer_copy                   (GtkTextBuffer      *buffer,
                                         guint32              time)
 {
-  cut_or_copy(buffer, time, FALSE);
+  cut_or_copy(buffer, time, FALSE, FALSE, TRUE);
 }
 
 
@@ -1656,7 +1705,7 @@ gtk_text_buffer_get_selection_bounds   (GtkTextBuffer      *buffer,
   g_return_val_if_fail (buffer != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
 
-  return gtk_text_btree_get_selection_bounds (buffer->tree, start, end);
+  return gtk_text_btree_get_selection_bounds (get_btree (buffer), start, end);
 }
 
 
@@ -1667,5 +1716,6 @@ gtk_text_buffer_get_selection_bounds   (GtkTextBuffer      *buffer,
 void
 gtk_text_buffer_spew(GtkTextBuffer *buffer)
 {
-  gtk_text_btree_spew(buffer->tree);
+  gtk_text_btree_spew(get_btree (buffer));
 }
+
index a8ef0eb65196cdbdbe57dfc464ed914bc388a0f5..3f164c5aeadedb8655d3baa711636d316306fb98 100644 (file)
@@ -30,7 +30,7 @@ struct _GtkTextBuffer {
   GtkObject parent_instance;
 
   GtkTextTagTable *tag_table;
-  GtkTextBTree *tree;
+  GtkTextBTree *btree;
 
   /* Text currently pasted to the clipboard */
   gchar *clipboard_text;
@@ -42,6 +42,8 @@ struct _GtkTextBuffer {
   GtkWidget *selection_widget;
   gboolean have_selection;
   gboolean selection_handlers_installed;
+  gboolean paste_interactive;
+  gboolean paste_default_editable;
 };
 
 struct _GtkTextBufferClass {
@@ -95,6 +97,7 @@ gint           gtk_text_buffer_get_line_count (GtkTextBuffer   *buffer);
 gint           gtk_text_buffer_get_char_count (GtkTextBuffer   *buffer);
 
 
+GtkTextTagTable* gtk_text_buffer_get_tag_table (GtkTextBuffer  *buffer);
 
 /* Insert into the buffer */
 void gtk_text_buffer_insert            (GtkTextBuffer *buffer,
@@ -104,71 +107,45 @@ void gtk_text_buffer_insert            (GtkTextBuffer *buffer,
 void gtk_text_buffer_insert_at_cursor  (GtkTextBuffer *buffer,
                                         const gchar   *text,
                                         gint           len);
-void gtk_text_buffer_insert_at_char    (GtkTextBuffer *buffer,
-                                        gint           char_pos,
-                                        const gchar   *text,
-                                        gint           len);
-void gtk_text_buffer_insert_after_line (GtkTextBuffer *buffer,
-                                        gint           after_this_line,
-                                        const gchar   *text,
-                                        gint           len);
 
+gboolean gtk_text_buffer_insert_interactive           (GtkTextBuffer *buffer,
+                                                       GtkTextIter   *iter,
+                                                       const gchar   *text,
+                                                       gint           len,
+                                                       gboolean       default_editable);
+gboolean gtk_text_buffer_insert_interactive_at_cursor (GtkTextBuffer *buffer,
+                                                       const gchar   *text,
+                                                       gint           len,
+                                                       gboolean       default_editable);
 
 
 /* Delete from the buffer */
+void     gtk_text_buffer_delete             (GtkTextBuffer *buffer,
+                                             GtkTextIter   *start_iter,
+                                             GtkTextIter   *end_iter);
+gboolean gtk_text_buffer_delete_interactive (GtkTextBuffer *buffer,
+                                             GtkTextIter   *start_iter,
+                                             GtkTextIter   *end_iter,
+                                             gboolean       default_editable);
+
+
 
-void gtk_text_buffer_delete           (GtkTextBuffer *buffer,
-                                       GtkTextIter   *start_iter,
-                                       GtkTextIter   *end_iter);
-void gtk_text_buffer_delete_chars     (GtkTextBuffer *buffer,
-                                       gint           start_char,
-                                       gint           end_char);
-void gtk_text_buffer_delete_lines     (GtkTextBuffer *buffer,
-                                       gint           start_line,
-                                       gint           end_line);
-void gtk_text_buffer_delete_from_line (GtkTextBuffer *buffer,
-                                       gint           line,
-                                       gint           start_char,
-                                       gint           end_char);
 /* Obtain strings from the buffer */
 gchar          *gtk_text_buffer_get_text            (GtkTextBuffer     *buffer,
                                                      const GtkTextIter *start_iter,
                                                      const GtkTextIter *end_iter,
                                                      gboolean           include_hidden_chars);
-gchar          *gtk_text_buffer_get_text_chars      (GtkTextBuffer     *buffer,
-                                                     gint               start_char,
-                                                     gint               end_char,
-                                                     gboolean           include_hidden_chars);
-gchar          *gtk_text_buffer_get_text_from_line  (GtkTextBuffer     *buffer,
-                                                     gint               line,
-                                                     gint               start_char,
-                                                     gint               end_char,
-                                                     gboolean           include_hidden_chars);
+
 gchar          *gtk_text_buffer_get_slice           (GtkTextBuffer     *buffer,
                                                      const GtkTextIter *start_iter,
                                                      const GtkTextIter *end_iter,
                                                      gboolean           include_hidden_chars);
-gchar          *gtk_text_buffer_get_slice_chars     (GtkTextBuffer     *buffer,
-                                                     gint               start_char,
-                                                     gint               end_char,
-                                                     gboolean           include_hidden_chars);
-gchar          *gtk_text_buffer_get_slice_from_line (GtkTextBuffer     *buffer,
-                                                     gint               line,
-                                                     gint               start_char,
-                                                     gint               end_char,
-                                                     gboolean           include_hidden_chars);
 
 /* Insert a pixmap */
 void gtk_text_buffer_insert_pixmap         (GtkTextBuffer *buffer,
                                             GtkTextIter   *iter,
                                             GdkPixmap     *pixmap,
                                             GdkBitmap     *mask);
-void gtk_text_buffer_insert_pixmap_at_char (GtkTextBuffer *buffer,
-                                            gint           char_index,
-                                            GdkPixmap     *pixmap,
-                                            GdkBitmap     *mask);
-
-
 
 /* Mark manipulation */
 GtkTextMark   *gtk_text_buffer_create_mark (GtkTextBuffer     *buffer,
@@ -191,68 +168,56 @@ void gtk_text_buffer_place_cursor (GtkTextBuffer     *buffer,
 
 
 /* Tag manipulation */
-void gtk_text_buffer_apply_tag_to_chars    (GtkTextBuffer     *buffer,
-                                            const gchar       *name,
-                                            gint               start_char,
-                                            gint               end_char);
-void gtk_text_buffer_remove_tag_from_chars (GtkTextBuffer     *buffer,
-                                            const gchar       *name,
-                                            gint               start_char,
-                                            gint               end_char);
 void gtk_text_buffer_apply_tag             (GtkTextBuffer     *buffer,
-                                            const gchar       *name,
+                                            GtkTextTag        *tag,
                                             const GtkTextIter *start_index,
                                             const GtkTextIter *end_index);
 void gtk_text_buffer_remove_tag            (GtkTextBuffer     *buffer,
+                                            GtkTextTag        *tag,
+                                            const GtkTextIter *start_index,
+                                            const GtkTextIter *end_index);
+void gtk_text_buffer_apply_tag_by_name     (GtkTextBuffer     *buffer,
+                                            const gchar       *name,
+                                            const GtkTextIter *start_index,
+                                            const GtkTextIter *end_index);
+void gtk_text_buffer_remove_tag_by_name    (GtkTextBuffer     *buffer,
                                             const gchar       *name,
                                             const GtkTextIter *start_index,
                                             const GtkTextIter *end_index);
-
 
 
 /* You can either ignore the return value, or use it to
-   set the attributes of the tag */
+ * set the attributes of the tag. tag_name can be NULL
+ */
 GtkTextTag    *gtk_text_buffer_create_tag (GtkTextBuffer *buffer,
                                            const gchar   *tag_name);
 
 /* Obtain iterators pointed at various places, then you can move the
    iterator around using the GtkTextIter operators */
+void gtk_text_buffer_get_iter_at_line_offset (GtkTextBuffer *buffer,
+                                              GtkTextIter   *iter,
+                                              gint           line_number,
+                                              gint           char_offset);
+void gtk_text_buffer_get_iter_at_offset      (GtkTextBuffer *buffer,
+                                              GtkTextIter   *iter,
+                                              gint           char_offset);
+void gtk_text_buffer_get_iter_at_line        (GtkTextBuffer *buffer,
+                                              GtkTextIter   *iter,
+                                              gint           line_number);
+void gtk_text_buffer_get_last_iter           (GtkTextBuffer *buffer,
+                                              GtkTextIter   *iter);
+void gtk_text_buffer_get_bounds              (GtkTextBuffer *buffer,
+                                              GtkTextIter   *start,
+                                              GtkTextIter   *end);
+void gtk_text_buffer_get_iter_at_mark        (GtkTextBuffer *buffer,
+                                              GtkTextIter   *iter,
+                                              GtkTextMark   *mark);
 
-void     gtk_text_buffer_get_iter_at_line_char (GtkTextBuffer *buffer,
-                                                GtkTextIter   *iter,
-                                                gint           line_number,
-                                                gint           char_number);
-void     gtk_text_buffer_get_iter_at_char      (GtkTextBuffer *buffer,
-                                                GtkTextIter   *iter,
-                                                gint           char_index);
-void     gtk_text_buffer_get_iter_at_line      (GtkTextBuffer *buffer,
-                                                GtkTextIter   *iter,
-                                                gint           line_number);
-void     gtk_text_buffer_get_last_iter         (GtkTextBuffer *buffer,
-                                                GtkTextIter   *iter);
-void     gtk_text_buffer_get_bounds            (GtkTextBuffer *buffer,
-                                                GtkTextIter   *start,
-                                                GtkTextIter   *end);
-void     gtk_text_buffer_get_iter_at_mark      (GtkTextBuffer *buffer,
-                                                GtkTextIter   *iter,
-                                                GtkTextMark   *mark);
 
 
 /* There's no get_first_iter because you just get the iter for
    line or char 0 */
 
-/*
-  Parses a string, read the man page for the Tk text widget; the only
-  variation from that is we don't support getting the index at a
-  certain pixel since the buffer has no pixel knowledge.  This
-  function is mostly useful for language bindings I think.
-*/
-gboolean gtk_text_buffer_get_iter_from_string (GtkTextBuffer *buffer,
-                                               GtkTextIter   *iter,
-                                               const gchar   *iter_string);
-
-
-
 GSList         *gtk_text_buffer_get_tags (GtkTextBuffer     *buffer,
                                           const GtkTextIter *iter);
 
@@ -269,16 +234,26 @@ void            gtk_text_buffer_set_modified            (GtkTextBuffer *buffer,
 void            gtk_text_buffer_set_clipboard_contents  (GtkTextBuffer *buffer,
                                                          const gchar   *text);
 const gchar    *gtk_text_buffer_get_clipboard_contents  (GtkTextBuffer *buffer);
+
+
 void            gtk_text_buffer_paste_primary_selection (GtkTextBuffer *buffer,
                                                          GtkTextIter   *override_location,
-                                                         guint32        time);
-gboolean        gtk_text_buffer_delete_selection        (GtkTextBuffer *buffer);
+                                                         guint32        time,
+                                                         gboolean       interactive,
+                                                         gboolean       default_editable);
+gboolean        gtk_text_buffer_delete_selection        (GtkTextBuffer *buffer,
+                                                         gboolean       interactive,
+                                                         gboolean       default_editable);
 void            gtk_text_buffer_cut                     (GtkTextBuffer *buffer,
-                                                         guint32        time);
+                                                         guint32        time,
+                                                         gboolean       interactive,
+                                                         gboolean       default_editable);
 void            gtk_text_buffer_copy                    (GtkTextBuffer *buffer,
                                                          guint32        time);
 void            gtk_text_buffer_paste_clipboard         (GtkTextBuffer *buffer,
-                                                         guint32        time);
+                                                         guint32        time,
+                                                         gboolean       interactive,
+                                                         gboolean       default_editable);
 gboolean        gtk_text_buffer_get_selection_bounds    (GtkTextBuffer *buffer,
                                                          GtkTextIter   *start,
                                                          GtkTextIter   *end);
@@ -302,6 +277,8 @@ gboolean gtk_text_buffer_find_regexp(GtkTextBuffer *buffer,
 /* INTERNAL private stuff */
 void            gtk_text_buffer_spew                   (GtkTextBuffer      *buffer);
 
+GtkTextBTree*   _gtk_text_buffer_get_btree             (GtkTextBuffer      *buffer);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 8fa44b3ff134c5dd1edc710bc855510625bc3b60..0ddcb378959c90b2344c782456401329f4ee9060 100644 (file)
@@ -585,21 +585,23 @@ gtk_text_layout_draw (GtkTextLayout *layout,
          GtkTextIter line_start, line_end;
          gint byte_count = gtk_text_line_byte_count (line);
          
-         gtk_text_btree_get_iter_at_line (layout->buffer->tree, &line_start,
+         gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
+                                           &line_start,
                                           line, 0);
-         gtk_text_btree_get_iter_at_line (layout->buffer->tree, &line_end,
+         gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
+                                           &line_end,
                                           line, byte_count - 1);
 
          if (gtk_text_iter_compare (&selection_start, &line_end) < 0 &&
              gtk_text_iter_compare (&selection_end, &line_start) > 0)
            {
              if (gtk_text_iter_compare (&selection_start, &line_start) >= 0)
-               selection_start_index = gtk_text_iter_get_line_byte (&selection_start);
+               selection_start_index = gtk_text_iter_get_line_index (&selection_start);
              else
                selection_start_index = -1;
 
              if (gtk_text_iter_compare (&selection_end, &line_end) <= 0)
-               selection_end_index = gtk_text_iter_get_line_byte (&selection_end);
+               selection_end_index = gtk_text_iter_get_line_index (&selection_end);
              else
                selection_end_index = byte_count;
            }
index 953045e0b4ebe0ab62eb0852c6d7d837f5fac2d9..48e6b17eda6d0f810d83a6af880fa377e5ac1205 100644 (file)
@@ -2,6 +2,7 @@
 #include "gtktextbtree.h"
 #include "gtktextiterprivate.h"
 #include "gtkdebug.h"
+#include <string.h>
 #include <ctype.h>
 
 typedef struct _GtkTextRealIter GtkTextRealIter;
@@ -34,9 +35,9 @@ struct _GtkTextRealIter {
      and ditto for char offsets. */
   gint segment_byte_offset;
   gint segment_char_offset;
-  /* These are here for binary-compatible expansion space. */
+  /* Pads are here for binary-compatible expansion space. */
   gpointer pad1;
-  gint pad2;
+  guint pad2;
 };
 
 /* These "set" functions should not assume any fields
@@ -114,7 +115,8 @@ iter_set_from_segment(GtkTextRealIter *iter,
 
 /* This function ensures that the segment-dependent information is
    truly computed lazily; often we don't need to do the full make_real
-   work. */
+   work. This ensures the btree and line are valid, but doesn't
+   update the segments. */
 static GtkTextRealIter*
 gtk_text_iter_make_surreal(const GtkTextIter *_iter)
 {
@@ -308,9 +310,9 @@ ensure_char_offsets(GtkTextRealIter *iter)
       g_assert(iter->line_byte_offset >= 0);
 
       gtk_text_line_byte_to_char_offsets(iter->line,
-                                          iter->line_byte_offset,
-                                          &iter->line_char_offset,
-                                          &iter->segment_char_offset);
+                                         iter->line_byte_offset,
+                                         &iter->line_char_offset,
+                                         &iter->segment_char_offset);
     }
 }
 
@@ -322,9 +324,9 @@ ensure_byte_offsets(GtkTextRealIter *iter)
       g_assert(iter->line_char_offset >= 0);
 
       gtk_text_line_char_to_byte_offsets(iter->line,
-                                          iter->line_char_offset,
-                                          &iter->line_byte_offset,
-                                          &iter->segment_byte_offset);
+                                         iter->line_char_offset,
+                                         &iter->line_byte_offset,
+                                         &iter->segment_byte_offset);
     }
 }
 
@@ -457,7 +459,7 @@ gtk_text_iter_get_segment_char(const GtkTextIter *iter)
 /* This function does not require a still-valid
    iterator */
 GtkTextLine*
-gtk_text_iter_get_line(const GtkTextIter *iter)
+gtk_text_iter_get_text_line(const GtkTextIter *iter)
 {
   const GtkTextRealIter *real;
 
@@ -487,7 +489,7 @@ gtk_text_iter_get_btree(const GtkTextIter *iter)
  */
 
 gint
-gtk_text_iter_get_char_index(const GtkTextIter *iter)
+gtk_text_iter_get_offset(const GtkTextIter *iter)
 {
   GtkTextRealIter *real;
 
@@ -512,7 +514,7 @@ gtk_text_iter_get_char_index(const GtkTextIter *iter)
 }
 
 gint
-gtk_text_iter_get_line_number(const GtkTextIter *iter)
+gtk_text_iter_get_line(const GtkTextIter *iter)
 {
   GtkTextRealIter *real;
 
@@ -533,7 +535,7 @@ gtk_text_iter_get_line_number(const GtkTextIter *iter)
 }
 
 gint
-gtk_text_iter_get_line_char(const GtkTextIter *iter)
+gtk_text_iter_get_line_offset(const GtkTextIter *iter)
 {
 
   GtkTextRealIter *real;
@@ -553,7 +555,7 @@ gtk_text_iter_get_line_char(const GtkTextIter *iter)
 }
 
 gint
-gtk_text_iter_get_line_byte(const GtkTextIter *iter)
+gtk_text_iter_get_line_index(const GtkTextIter *iter)
 {
   GtkTextRealIter *real;
 
@@ -690,6 +692,38 @@ gtk_text_iter_get_pixmap      (const GtkTextIter *iter,
     }
 }
 
+GSList*
+gtk_text_iter_get_marks (const GtkTextIter *iter)
+{
+  GtkTextRealIter *real;
+  GtkTextLineSegment *seg;
+  GSList *retval;
+  
+  g_return_val_if_fail(iter != NULL, NULL);
+  
+  real = gtk_text_iter_make_real(iter);
+
+  if (real == NULL)
+    return NULL;
+
+  check_invariants(iter);
+  
+  retval = NULL;
+  seg = real->any_segment;
+  while (seg != real->segment)
+    {
+      if (seg->type == &gtk_text_left_mark_type ||
+          seg->type == &gtk_text_right_mark_type)
+        retval = g_slist_prepend(retval, (GtkTextMark*)seg);
+      
+      seg = seg->next;
+    }
+
+  /* The returned list isn't guaranteed to be in any special order,
+     and it isn't. */
+  return retval;
+}
+
 GSList*
 gtk_text_iter_get_toggled_tags  (const GtkTextIter  *iter,
                                   gboolean             toggled_on)
@@ -858,6 +892,43 @@ gtk_text_iter_has_tag           (const GtkTextIter   *iter,
     }
 }
 
+gboolean
+gtk_text_iter_editable (const GtkTextIter *iter,
+                        gboolean           default_setting)
+{
+  GtkTextStyleValues *values;
+  gboolean retval;
+  
+  values = gtk_text_style_values_new ();
+
+  values->editable = default_setting;
+
+  gtk_text_iter_get_style_values (iter, values);
+
+  retval = values->editable;
+  
+  gtk_text_style_values_unref (values);
+
+  return retval;
+}
+
+static gchar*
+gtk_text_iter_get_language (const GtkTextIter *iter)
+{
+  GtkTextStyleValues *values;
+  gchar *retval;
+  
+  values = gtk_text_style_values_new ();
+
+  gtk_text_iter_get_style_values (iter, values);
+
+  retval = g_strdup (values->language);
+  
+  gtk_text_style_values_unref (values);
+
+  return retval;
+}
+
 gboolean
 gtk_text_iter_starts_line (const GtkTextIter   *iter)
 {
@@ -893,6 +964,29 @@ gtk_text_iter_ends_line (const GtkTextIter   *iter)
   return gtk_text_iter_get_char(iter) == '\n';
 }
 
+gboolean
+gtk_text_iter_is_last (const GtkTextIter *iter)
+{
+  GtkTextRealIter *real;
+  
+  g_return_val_if_fail(iter != NULL, FALSE);
+  
+  real = gtk_text_iter_make_surreal(iter);
+
+  if (real == NULL)
+    return FALSE;  
+
+  check_invariants(iter);
+  
+  return gtk_text_line_is_last(real->line);
+}
+
+gboolean
+gtk_text_iter_is_first (const GtkTextIter *iter)
+{
+  return gtk_text_iter_get_offset (iter) == 0;
+}
+
 gint
 gtk_text_iter_get_chars_in_line (const GtkTextIter   *iter)
 {
@@ -933,10 +1027,45 @@ gtk_text_iter_get_chars_in_line (const GtkTextIter   *iter)
   return count;
 }
 
+gboolean
+gtk_text_iter_get_style_values (const GtkTextIter  *iter,
+                                GtkTextStyleValues *values)
+{
+  GtkTextTag** tags;
+  gint tag_count = 0;
+
+  /* Get the tags at this spot */
+  tags = gtk_text_btree_get_tags (iter, &tag_count);
+
+  /* No tags, use default style */
+  if (tags == NULL || tag_count == 0)
+    {
+      if (tags)
+        g_free (tags);
+
+      return FALSE;
+    }
+  
+  /* Sort tags in ascending order of priority */
+  gtk_text_tag_array_sort (tags, tag_count);
+  
+  gtk_text_style_values_fill_from_tags (values,
+                                        tags,
+                                        tag_count);
+
+  g_free (tags);
+
+  return TRUE;
+}
+
 /*
  * Increments/decrements
  */
 
+/* The return value of this indicates WHETHER WE MOVED.
+ * The return value of public functions indicates
+ * (MOVEMENT OCCURRED && NEW ITER IS DEREFERENCEABLE)
+ */
 static gboolean
 forward_line_leaving_caches_unmodified(GtkTextRealIter *real)
 {
@@ -961,7 +1090,7 @@ forward_line_leaving_caches_unmodified(GtkTextRealIter *real)
       real->segment = real->any_segment;
       while (real->segment->char_count == 0)
         real->segment = real->segment->next;
-      
+
       return TRUE;
     }
   else
@@ -1126,8 +1255,11 @@ gtk_text_iter_forward_indexable_segment(GtkTextIter *iter)
           g_assert(gtk_text_iter_starts_line(iter));
 
           check_invariants(iter);
-          
-          return TRUE;
+
+          if (gtk_text_iter_is_last (iter))
+            return FALSE;
+          else
+            return TRUE;
         }
       else
         {
@@ -1145,10 +1277,12 @@ gtk_text_iter_backward_indexable_segment(GtkTextIter *iter)
 {
   g_warning("FIXME");
 
+
+  return FALSE;
 }
 
 gboolean
-gtk_text_iter_forward_char(GtkTextIter *iter)
+gtk_text_iter_next_char(GtkTextIter *iter)
 {
   GtkTextRealIter *real;
   
@@ -1166,7 +1300,7 @@ gtk_text_iter_forward_char(GtkTextIter *iter)
 }
 
 gboolean
-gtk_text_iter_backward_char(GtkTextIter *iter)
+gtk_text_iter_prev_char(GtkTextIter *iter)
 {
   g_return_val_if_fail(iter != NULL, FALSE);
 
@@ -1224,17 +1358,23 @@ gtk_text_iter_forward_chars(GtkTextIter *iter, gint count)
 
       check_invariants(iter);
       
-      current_char_index = gtk_text_iter_get_char_index(iter);
+      current_char_index = gtk_text_iter_get_offset(iter);
 
       if (current_char_index == gtk_text_btree_char_count(real->tree))
         return FALSE; /* can't move forward */
       
       new_char_index = current_char_index + count;
-      gtk_text_iter_set_char_index(iter, new_char_index);
+      gtk_text_iter_set_offset(iter, new_char_index);
 
       check_invariants(iter);
 
-      return TRUE;
+      /* Return FALSE if we're on the non-dereferenceable end
+       * iterator.
+       */
+      if (gtk_text_iter_is_last (iter))
+        return FALSE;
+      else
+        return TRUE;
     }
 }
 
@@ -1300,7 +1440,7 @@ gtk_text_iter_backward_chars(GtkTextIter *iter, gint count)
       gint current_char_index;
       gint new_char_index;
       
-      current_char_index = gtk_text_iter_get_char_index(iter);
+      current_char_index = gtk_text_iter_get_offset(iter);
 
       if (current_char_index == 0)
         return FALSE; /* can't move backward */
@@ -1308,7 +1448,7 @@ gtk_text_iter_backward_chars(GtkTextIter *iter, gint count)
       new_char_index = current_char_index - count;
       if (new_char_index < 0)
         new_char_index = 0;
-      gtk_text_iter_set_char_index(iter, new_char_index);
+      gtk_text_iter_set_offset(iter, new_char_index);
 
       check_invariants(iter);
       
@@ -1336,8 +1476,11 @@ gtk_text_iter_forward_line(GtkTextIter *iter)
       adjust_line_number(real, 1);
 
       check_invariants(iter);
-      
-      return TRUE;
+
+      if (gtk_text_iter_is_last (iter))
+        return FALSE;
+      else
+        return TRUE;
     }
   else
     {
@@ -1423,13 +1566,13 @@ gtk_text_iter_forward_lines(GtkTextIter *iter, gint count)
     {
       gint old_line;
       
-      old_line = gtk_text_iter_get_line_number(iter);
+      old_line = gtk_text_iter_get_line(iter);
       
-      gtk_text_iter_set_line_number(iter, old_line + count);
+      gtk_text_iter_set_line(iter, old_line + count);
 
       check_invariants(iter);
       
-      return (gtk_text_iter_get_line_number(iter) != old_line);
+      return (gtk_text_iter_get_line(iter) != old_line);
     }
 }
 
@@ -1448,93 +1591,161 @@ gtk_text_iter_backward_lines(GtkTextIter *iter, gint count)
     {
       gint old_line;
       
-      old_line = gtk_text_iter_get_line_number(iter);
+      old_line = gtk_text_iter_get_line(iter);
       
-      gtk_text_iter_set_line_number(iter, MAX(old_line - count, 0));
+      gtk_text_iter_set_line(iter, MAX(old_line - count, 0));
 
-      return (gtk_text_iter_get_line_number(iter) != old_line);
+      return (gtk_text_iter_get_line(iter) != old_line);
     }
 }
 
-static gboolean
-is_word_char(gunichar ch, gpointer user_data)
-{
-  /* will likely need some i18n help FIXME */
-  return isalpha(ch);
-}
+typedef gboolean (* FindLogAttrFunc) (PangoLogAttr *attrs,
+                                      gint          offset,
+                                      gint          min_offset,
+                                      gint          len,
+                                      gint         *found_offset);     
 
 static gboolean
-is_not_word_char(gunichar ch, gpointer user_data)
+find_word_end_func (PangoLogAttr *attrs,
+                    gint          offset,
+                    gint          min_offset,
+                    gint          len,
+                    gint         *found_offset)
 {
-  return !is_word_char(ch, user_data);
+  ++offset; /* We always go to the NEXT word end */
+  
+  /* Find start of next word */
+  while (offset < min_offset + len &&
+         !attrs[offset].is_word_stop)
+    ++offset;
+  
+  /* Find end */
+  while (offset < min_offset + len &&
+         !attrs[offset].is_white)
+    ++offset;
+  
+  *found_offset = offset;
+
+  return offset < min_offset + len;
 }
 
 static gboolean
-gtk_text_iter_is_in_word(const GtkTextIter *iter)
+find_word_start_func (PangoLogAttr *attrs,
+                      gint          offset,
+                      gint          min_offset,
+                      gint          len,
+                      gint         *found_offset)
 {
-  gint ch;
-
-  ch = gtk_text_iter_get_char(iter);
+  --offset; /* We always go to the NEXT word start */
+  
+  /* Find end of prev word */
+  while (offset >= min_offset &&
+         attrs[offset].is_white)
+    --offset;
+  
+  /* Find start */
+  while (offset >= min_offset &&
+         !attrs[offset].is_word_stop)
+    --offset;
+  
+  *found_offset = offset;
 
-  return is_word_char(ch, NULL);
+  return offset >= min_offset;
 }
 
-gboolean
-gtk_text_iter_forward_word_end(GtkTextIter      *iter)
-{  
-  gboolean in_word;
+/* FIXME this function is very, very gratuitously slow */
+static gboolean
+find_by_log_attrs (GtkTextIter *iter,
+                   FindLogAttrFunc func,
+                   gboolean forward)
+{
+  GtkTextIter orig;
   GtkTextIter start;
+  GtkTextIter end;
+  gchar *paragraph;
+  gint char_len, byte_len;
+  PangoLogAttr *attrs;
+  int offset;
+  gboolean found = FALSE;
   
   g_return_val_if_fail(iter != NULL, FALSE);
 
+  orig = *iter;
   start = *iter;
+  end = *iter;
+
+  gtk_text_iter_set_line_offset (&start, 0);
+  gtk_text_iter_forward_to_newline (&end);
   
-  in_word = gtk_text_iter_is_in_word(iter);
+  paragraph = gtk_text_iter_get_text (&start, &end);
+  char_len = g_utf8_strlen (paragraph, -1);
+  byte_len = strlen (paragraph);
 
-  if (!in_word)
+  offset = gtk_text_iter_get_line_offset (iter);
+  
+  if (char_len > 0 && offset < char_len)
     {
-      if (!gtk_text_iter_forward_find_char(iter, is_word_char, NULL))
-        return !gtk_text_iter_equal(iter, &start);
-      else
-        in_word = TRUE;
-    }
+      gchar *lang;
+      
+      attrs = g_new (PangoLogAttr, char_len);
+      
+      lang = gtk_text_iter_get_language (iter);
 
-  g_assert(in_word);
-  
-  gtk_text_iter_forward_find_char(iter, is_not_word_char, NULL);
+      pango_get_log_attrs (paragraph, byte_len, -1,
+                           lang,
+                           attrs);
 
-  return !gtk_text_iter_equal(iter, &start);
-}
+      g_free (lang);
 
-gboolean
-gtk_text_iter_backward_word_start(GtkTextIter      *iter)
-{
-  gboolean in_word;
-  GtkTextIter start;
+      found = (* func) (attrs, offset, 0, char_len, &offset);
+      
+      g_free (attrs);
+    }
   
-  g_return_val_if_fail(iter != NULL, FALSE);
-
-  start = *iter;
+  g_free (paragraph);
   
-  in_word = gtk_text_iter_is_in_word(iter);
-
-  if (!in_word)
+  if (!found)
     {
-      if (!gtk_text_iter_backward_find_char(iter, is_word_char, NULL))
-        return !gtk_text_iter_equal(iter, &start);
+      if (forward)
+        {
+          if (gtk_text_iter_forward_line (iter))
+            return find_by_log_attrs (iter, func, forward);
+          else
+            return FALSE;
+        }
       else
-        in_word = TRUE;
+        {
+          if (gtk_text_iter_backward_line (iter))
+            return find_by_log_attrs (iter, func, forward);
+          else
+            return FALSE;
+        }
     }
+  else
+    {     
+      gtk_text_iter_set_line_offset (iter, offset);
+      
+      return
+        !gtk_text_iter_equal(iter, &orig) &&
+        !gtk_text_iter_is_last (iter);
+    }
+}
 
-  g_assert(in_word);
-  
-  gtk_text_iter_backward_find_char(iter, is_not_word_char, NULL);
-  gtk_text_iter_forward_char(iter); /* point to first char of word,
-                                        not first non-word char. */
-  
-  return !gtk_text_iter_equal(iter, &start);
+gboolean
+gtk_text_iter_forward_word_end(GtkTextIter *iter)
+{
+  return find_by_log_attrs (iter, find_word_end_func, TRUE);
+}
+
+gboolean
+gtk_text_iter_backward_word_start(GtkTextIter      *iter)
+{
+  return find_by_log_attrs (iter, find_word_start_func, FALSE);
 }
 
+/* FIXME a loop around a truly slow function means
+ * a truly spectacularly slow function.
+ */
 gboolean
 gtk_text_iter_forward_word_ends(GtkTextIter      *iter,
                                  gint               count)
@@ -1575,64 +1786,8 @@ gtk_text_iter_backward_word_starts(GtkTextIter      *iter,
   return TRUE;
 }
 
-/* up/down lines maintain the char offset, while forward/backward lines
-   always sets the char offset to 0. */
-gboolean
-gtk_text_iter_up_lines        (GtkTextIter *iter,
-                                gint count)
-{
-  gint char_offset;
-
-  if (count < 0)
-    return gtk_text_iter_down_lines(iter, 0 - count);
-  
-  char_offset = gtk_text_iter_get_line_char(iter);
-
-  if (!gtk_text_iter_backward_line(iter))
-    return FALSE;
-  --count;
-  
-  while (count > 0)
-    {
-      if (!gtk_text_iter_backward_line(iter))
-        break;
-      --count;
-    }
-
-  gtk_text_iter_set_line_char(iter, char_offset);
-  
-  return TRUE;
-}
-
-gboolean
-gtk_text_iter_down_lines        (GtkTextIter *iter,
-                                  gint count)
-{
-  gint char_offset;
-
-  if (count < 0)
-    return gtk_text_iter_up_lines(iter, 0 - count);
-  
-  char_offset = gtk_text_iter_get_line_char(iter);
-
-  if (!gtk_text_iter_forward_line(iter))
-    return FALSE;
-  --count;
-  
-  while (count > 0)
-    {
-      if (!gtk_text_iter_forward_line(iter))
-        break;
-      --count;
-    }
-
-  gtk_text_iter_set_line_char(iter, char_offset);
-  
-  return TRUE;
-}
-
 void
-gtk_text_iter_set_line_char(GtkTextIter *iter,
+gtk_text_iter_set_line_offset(GtkTextIter *iter,
                              gint char_on_line)
 {
   GtkTextRealIter *real;
@@ -1652,7 +1807,7 @@ gtk_text_iter_set_line_char(GtkTextIter *iter,
 }
 
 void
-gtk_text_iter_set_line_number(GtkTextIter *iter, gint line_number)
+gtk_text_iter_set_line(GtkTextIter *iter, gint line_number)
 {
   GtkTextLine *line;
   gint real_line;
@@ -1678,7 +1833,7 @@ gtk_text_iter_set_line_number(GtkTextIter *iter, gint line_number)
 }
 
 void
-gtk_text_iter_set_char_index(GtkTextIter *iter, gint char_index)
+gtk_text_iter_set_offset(GtkTextIter *iter, gint char_index)
 {
   GtkTextLine *line;
   GtkTextRealIter *real;
@@ -1737,13 +1892,13 @@ gtk_text_iter_forward_to_newline(GtkTextIter *iter)
   
   g_return_val_if_fail(iter != NULL, FALSE);
   
-  current_offset = gtk_text_iter_get_line_char(iter);
+  current_offset = gtk_text_iter_get_line_offset(iter);
   new_offset = gtk_text_iter_get_chars_in_line(iter) - 1;
 
   if (current_offset < new_offset)
     {
       /* Move to end of this line. */
-      gtk_text_iter_set_line_char(iter, new_offset);
+      gtk_text_iter_set_line_offset(iter, new_offset);
       return TRUE;
     }
   else
@@ -1760,8 +1915,8 @@ gtk_text_iter_forward_to_newline(GtkTextIter *iter)
 }
 
 gboolean
-gtk_text_iter_forward_find_tag_toggle (GtkTextIter *iter,
-                                        GtkTextTag  *tag)
+gtk_text_iter_forward_to_tag_toggle (GtkTextIter *iter,
+                                     GtkTextTag  *tag)
 {
   GtkTextLine *next_line;
   GtkTextLine *current_line;
@@ -1813,13 +1968,22 @@ gtk_text_iter_forward_find_tag_toggle (GtkTextIter *iter,
         }
     }
 
+  /* Check end iterator for tags */
+  if (gtk_text_iter_toggles_tag(iter, tag))
+    {
+      /* If there's a toggle here, it isn't indexable so
+         any_segment can't be the indexable segment. */
+      g_assert(real->any_segment != real->segment);
+      return TRUE;
+    }
+  
   /* Reached end of buffer */
   return FALSE;
 }
 
 gboolean
-gtk_text_iter_backward_find_tag_toggle (GtkTextIter *iter,
-                                         GtkTextTag  *tag)
+gtk_text_iter_backward_to_tag_toggle (GtkTextIter *iter,
+                                      GtkTextTag  *tag)
 {
 
   g_warning("FIXME");
@@ -1827,7 +1991,7 @@ gtk_text_iter_backward_find_tag_toggle (GtkTextIter *iter,
 
 static gboolean
 matches_pred(GtkTextIter *iter,
-             GtkTextViewCharPredicate pred,
+             GtkTextCharPredicate pred,
              gpointer user_data)
 {
   gint ch;
@@ -1839,13 +2003,13 @@ matches_pred(GtkTextIter *iter,
 
 gboolean
 gtk_text_iter_forward_find_char (GtkTextIter *iter,
-                                  GtkTextViewCharPredicate pred,
+                                  GtkTextCharPredicate pred,
                                   gpointer user_data)
 {
   g_return_val_if_fail(iter != NULL, FALSE);
   g_return_val_if_fail(pred != NULL, FALSE);
 
-  while (gtk_text_iter_forward_char(iter))
+  while (gtk_text_iter_next_char(iter))
     {
       if (matches_pred(iter, pred, user_data))
         return TRUE;
@@ -1856,13 +2020,13 @@ gtk_text_iter_forward_find_char (GtkTextIter *iter,
 
 gboolean
 gtk_text_iter_backward_find_char (GtkTextIter *iter,
-                                   GtkTextViewCharPredicate pred,
+                                   GtkTextCharPredicate pred,
                                    gpointer user_data)
 {
   g_return_val_if_fail(iter != NULL, FALSE);
   g_return_val_if_fail(pred != NULL, FALSE);
 
-  while (gtk_text_iter_backward_char(iter))
+  while (gtk_text_iter_prev_char(iter))
     {
       if (matches_pred(iter, pred, user_data))
         return TRUE;
@@ -1871,6 +2035,212 @@ gtk_text_iter_backward_find_char (GtkTextIter *iter,
   return FALSE;
 }
 
+static gboolean
+lines_match (const GtkTextIter *start,
+             const gchar **lines,
+             gboolean visible_only,
+             gboolean slice,
+             GtkTextIter *match_start)
+{
+  GtkTextIter next;
+  gchar *line_text;
+  const gchar *found;
+  gint offset;
+  
+  if (*lines == NULL || **lines == '\0')
+    return TRUE;
+  
+  next = *start;
+  gtk_text_iter_forward_line (&next);
+
+  gtk_text_iter_spew (start, "start");
+  gtk_text_iter_spew (&next, "next");
+  
+  /* No more text in buffer, but *lines is nonempty */
+  if (gtk_text_iter_equal (start, &next))
+    {
+      return FALSE;
+    }
+
+  if (slice)
+    {
+      if (visible_only)
+        line_text = gtk_text_iter_get_visible_slice (start, &next);
+      else
+        line_text = gtk_text_iter_get_slice (start, &next);
+    }
+  else
+    {
+      /* FIXME */
+      g_warning ("Searching for non-slice text is currently broken (you must include 'unknown char' for pixmaps in order to match them)");
+      if (visible_only)
+        line_text = gtk_text_iter_get_visible_text (start, &next);
+      else
+        line_text = gtk_text_iter_get_text (start, &next);
+    }
+  
+  if (match_start) /* if this is the first line we're matching */
+    found = strstr (line_text, *lines);
+  else
+    {
+      /* If it's not the first line, we have to match from the
+       * start of the line.
+       */
+      if (strncmp (line_text, *lines, strlen (*lines)) == 0)
+        found = line_text;
+      else
+        found = NULL;
+    }
+
+  if (found == NULL)
+    {
+      g_free (line_text);
+      return FALSE;
+    }
+  
+  /* Get offset to start of search string */
+  offset = g_utf8_strlen (line_text, found - line_text);
+  
+  next = *start;
+  
+  /* If match start needs to be returned, set it to the
+   * start of the search string.
+   */
+  if (match_start)
+    {
+      *match_start = next;
+      gtk_text_iter_forward_chars (match_start, offset);
+    }
+
+  /* Go to end of search string */
+  offset += g_utf8_strlen (*lines, -1);
+
+  gtk_text_iter_forward_chars (&next, offset);
+  
+  g_free (line_text);
+
+  ++lines;
+
+  /* pass NULL for match_start, since we don't need to find the
+   * start again.
+   */
+  return lines_match (&next, lines, visible_only, slice, NULL);
+}
+
+/* strsplit() that retains the delimiter as part of the string. */
+static gchar **
+strbreakup (const char *string,
+            const char *delimiter,
+            gint        max_tokens)
+{
+  GSList *string_list = NULL, *slist;
+  gchar **str_array, *s;
+  guint i, n = 1;
+
+  g_return_val_if_fail (string != NULL, NULL);
+  g_return_val_if_fail (delimiter != NULL, NULL);
+
+  if (max_tokens < 1)
+    max_tokens = G_MAXINT;
+
+  s = strstr (string, delimiter);
+  if (s)
+    {
+      guint delimiter_len = strlen (delimiter);
+
+      do
+       {
+         guint len;
+         gchar *new_string;
+
+         len = s - string + delimiter_len;
+         new_string = g_new (gchar, len + 1);
+         strncpy (new_string, string, len);
+         new_string[len] = 0;
+         string_list = g_slist_prepend (string_list, new_string);
+         n++;
+         string = s + delimiter_len;
+         s = strstr (string, delimiter);
+       }
+      while (--max_tokens && s);
+    }
+  if (*string)
+    {
+      n++;
+      string_list = g_slist_prepend (string_list, g_strdup (string));
+    }
+
+  str_array = g_new (gchar*, n);
+
+  i = n - 1;
+
+  str_array[i--] = NULL;
+  for (slist = string_list; slist; slist = slist->next)
+    str_array[i--] = slist->data;
+
+  g_slist_free (string_list);
+
+  return str_array;
+}
+
+gboolean
+gtk_text_iter_forward_search (GtkTextIter *iter,
+                              const char  *str,
+                              gboolean visible_only,
+                              gboolean slice)
+{
+  gchar **lines = NULL;
+  GtkTextIter match;
+  gboolean retval = FALSE;
+  GtkTextIter search;
+  
+  g_return_val_if_fail (iter != NULL, FALSE);
+  g_return_val_if_fail (str != NULL, FALSE);
+
+  if (*str == '\0')
+    return TRUE; /* we found the empty string */
+  
+  /* locate all lines */
+
+  lines = strbreakup (str, "\n", -1);
+  
+  search = *iter;
+
+  do
+    {      
+      /* This loop has an inefficient worst-case, where
+       * gtk_text_iter_get_text() is called repeatedly on
+       * a single line.
+       */
+      if (lines_match (&search, (const gchar**)lines, visible_only, slice, &match))
+        {
+          retval = TRUE;
+          
+          *iter = match;
+          
+          break;
+        }
+    }
+  while (gtk_text_iter_forward_line (&search));
+  
+  g_strfreev ((gchar**)lines);
+
+  return retval;
+}
+
+gboolean
+gtk_text_iter_backward_search (GtkTextIter *iter,
+                               const char  *str,
+                               gboolean visible_only,
+                               gboolean slice)
+{
+  g_return_val_if_fail (iter != NULL, FALSE);
+  g_return_val_if_fail (str != NULL, FALSE);
+
+
+
+}
+
 /*
  * Comparisons
  */
@@ -1949,8 +2319,8 @@ gtk_text_iter_compare(const GtkTextIter *lhs, const GtkTextIter *rhs)
     {
       gint line1, line2;
       
-      line1 = gtk_text_iter_get_line_number(lhs);
-      line2 = gtk_text_iter_get_line_number(rhs);
+      line1 = gtk_text_iter_get_line(lhs);
+      line2 = gtk_text_iter_get_line(rhs);
       if (line1 < line2)
         return -1;
       else if (line1 > line2)
@@ -2096,7 +2466,7 @@ gtk_text_btree_get_iter_at_first_toggle (GtkTextBTree   *tree,
   else
     {
       iter_init_from_byte_offset(iter, tree, line, 0);
-      gtk_text_iter_forward_find_tag_toggle(iter, tag);
+      gtk_text_iter_forward_to_tag_toggle(iter, tag);
       check_invariants(iter);
       return TRUE;
     }
@@ -2124,23 +2494,12 @@ gtk_text_btree_get_iter_at_last_toggle  (GtkTextBTree   *tree,
   else
     {
       iter_init_from_byte_offset(iter, tree, line, -1);
-      gtk_text_iter_backward_find_tag_toggle(iter, tag);
+      gtk_text_iter_backward_to_tag_toggle(iter, tag);
       check_invariants(iter);
       return TRUE;
     }
 }
 
-gboolean
-gtk_text_btree_get_iter_from_string (GtkTextBTree *tree,
-                                      GtkTextIter *iter,
-                                      const gchar *string)
-{
-  g_return_val_if_fail(iter != NULL, FALSE);
-  g_return_val_if_fail(tree != NULL, FALSE);
-  
-  g_warning("FIXME");
-}
-
 gboolean
 gtk_text_btree_get_iter_at_mark_name (GtkTextBTree *tree,
                                        GtkTextIter *iter,
@@ -2176,7 +2535,7 @@ gtk_text_btree_get_iter_at_mark (GtkTextBTree *tree,
   
   iter_init_from_segment(iter, tree,
                          seg->body.mark.line, seg);
-  g_assert(seg->body.mark.line == gtk_text_iter_get_line(iter));
+  g_assert(seg->body.mark.line == gtk_text_iter_get_text_line(iter));
   check_invariants(iter);
 }
 
@@ -2207,10 +2566,10 @@ gtk_text_iter_spew (const GtkTextIter *iter, const gchar *desc)
       check_invariants(iter);
       g_print(" %20s: line %d / char %d / line char %d / line byte %d\n",
              desc,
-             gtk_text_iter_get_line_number(iter),
-             gtk_text_iter_get_char_index(iter),
-             gtk_text_iter_get_line_char(iter),
-             gtk_text_iter_get_line_byte(iter));
+             gtk_text_iter_get_line(iter),
+             gtk_text_iter_get_offset(iter),
+             gtk_text_iter_get_line_offset(iter),
+             gtk_text_iter_get_line_index(iter));
       check_invariants(iter);
     }
 }
index 2e86e47b0d7ae72360af1ac61a5c23a32b80ef62..1114e3226d61d8333ef4adfeefbdc36f55960f03 100644 (file)
@@ -28,7 +28,7 @@ struct _GtkTextIter {
   gpointer dummy8;
   gint dummy9;
   gpointer pad1;
-  gint pad2;
+  guint pad2;
 };
 
 
@@ -46,10 +46,12 @@ void         gtk_text_iter_free     (GtkTextIter       *iter);
 /*
  * Convert to different kinds of index
  */
-gint     gtk_text_iter_get_char_index  (const GtkTextIter *iter);
-gint     gtk_text_iter_get_line_number (const GtkTextIter *iter);
-gint     gtk_text_iter_get_line_char   (const GtkTextIter *iter);
-gint     gtk_text_iter_get_line_byte   (const GtkTextIter *iter);
+
+gint gtk_text_iter_get_offset      (const GtkTextIter *iter);
+gint gtk_text_iter_get_line        (const GtkTextIter *iter);
+gint gtk_text_iter_get_line_offset (const GtkTextIter *iter);
+gint gtk_text_iter_get_line_index  (const GtkTextIter *iter);
+
 
 /*
  * "Dereference" operators
@@ -72,19 +74,21 @@ gchar   *gtk_text_iter_get_visible_text  (const GtkTextIter  *start,
 
 /* Returns TRUE if the iterator pointed at a pixmap */
 gboolean gtk_text_iter_get_pixmap        (const GtkTextIter  *iter,
-                                           GdkPixmap          **pixmap,
-                                           GdkBitmap          **mask);
+                                          GdkPixmap          **pixmap,
+                                          GdkBitmap          **mask);
+
+GSList  *gtk_text_iter_get_marks         (const GtkTextIter  *iter);
 
 /* Return list of tags toggled at this point (toggled_on determines
    whether the list is of on-toggles or off-toggles) */
 GSList  *gtk_text_iter_get_toggled_tags  (const GtkTextIter  *iter,
-                                           gboolean             toggled_on);
+                                          gboolean             toggled_on);
 
 gboolean gtk_text_iter_begins_tag        (const GtkTextIter  *iter,
-                                           GtkTextTag         *tag);
+                                          GtkTextTag         *tag);
 
 gboolean gtk_text_iter_ends_tag          (const GtkTextIter  *iter,
-                                           GtkTextTag         *tag);
+                                          GtkTextTag         *tag);
 
 gboolean gtk_text_iter_toggles_tag       (const GtkTextIter  *iter,
                                            GtkTextTag         *tag);
@@ -92,78 +96,91 @@ gboolean gtk_text_iter_toggles_tag       (const GtkTextIter  *iter,
 gboolean gtk_text_iter_has_tag           (const GtkTextIter   *iter,
                                            GtkTextTag          *tag);
 
+gboolean gtk_text_iter_editable          (const GtkTextIter   *iter,
+                                          gboolean             default_setting);
+
 gboolean gtk_text_iter_starts_line       (const GtkTextIter   *iter);
 gboolean gtk_text_iter_ends_line         (const GtkTextIter   *iter);
 
 gint     gtk_text_iter_get_chars_in_line (const GtkTextIter   *iter);
 
+gboolean gtk_text_iter_get_style_values  (const GtkTextIter    *iter,
+                                          GtkTextStyleValues   *values);
+
+gboolean gtk_text_iter_is_last           (const GtkTextIter    *iter);
+gboolean gtk_text_iter_is_first          (const GtkTextIter    *iter);
+
 /*
  * Moving around the buffer
  */
-gboolean gtk_text_iter_forward_char    (GtkTextIter       *iter);
-gboolean gtk_text_iter_backward_char   (GtkTextIter       *iter);
-gboolean gtk_text_iter_forward_chars   (GtkTextIter       *iter,
-                                         gint                count);
-gboolean gtk_text_iter_backward_chars  (GtkTextIter       *iter,
-                                         gint                count);
-gboolean gtk_text_iter_forward_line    (GtkTextIter       *iter);
-gboolean gtk_text_iter_backward_line   (GtkTextIter       *iter);
-gboolean gtk_text_iter_forward_lines   (GtkTextIter       *iter,
-                                         gint                count);
-gboolean gtk_text_iter_backward_lines  (GtkTextIter       *iter,
-                                         gint                count);
-gboolean gtk_text_iter_forward_word_ends(GtkTextIter      *iter,
-                                          gint               count);
-gboolean gtk_text_iter_backward_word_starts(GtkTextIter      *iter,
-                                             gint               count);
-gboolean gtk_text_iter_forward_word_end(GtkTextIter      *iter);
-gboolean gtk_text_iter_backward_word_start(GtkTextIter      *iter);
-
-gboolean gtk_text_iter_up_lines        (GtkTextIter *iter,
-                                         gint count);
-
-gboolean gtk_text_iter_down_lines        (GtkTextIter *iter,
-                                           gint count);
-
-void     gtk_text_iter_set_char_index  (GtkTextIter       *iter,
-                                         gint                char_index);
-void     gtk_text_iter_set_line_number (GtkTextIter       *iter,
-                                         gint                line_number);
-void     gtk_text_iter_set_line_char   (GtkTextIter       *iter,
-                                         gint                char_on_line);
-
-void     gtk_text_iter_forward_to_end  (GtkTextIter       *iter);
-gboolean gtk_text_iter_forward_to_newline(GtkTextIter     *iter);
+
+gboolean gtk_text_iter_next_char            (GtkTextIter *iter);
+gboolean gtk_text_iter_prev_char            (GtkTextIter *iter);
+gboolean gtk_text_iter_forward_chars        (GtkTextIter *iter,
+                                             gint         count);
+gboolean gtk_text_iter_backward_chars       (GtkTextIter *iter,
+                                             gint         count);
+gboolean gtk_text_iter_forward_line         (GtkTextIter *iter);
+gboolean gtk_text_iter_backward_line        (GtkTextIter *iter);
+gboolean gtk_text_iter_forward_lines        (GtkTextIter *iter,
+                                             gint         count);
+gboolean gtk_text_iter_backward_lines       (GtkTextIter *iter,
+                                             gint         count);
+gboolean gtk_text_iter_forward_word_ends    (GtkTextIter *iter,
+                                             gint         count);
+gboolean gtk_text_iter_backward_word_starts (GtkTextIter *iter,
+                                             gint         count);
+gboolean gtk_text_iter_forward_word_end     (GtkTextIter *iter);
+gboolean gtk_text_iter_backward_word_start  (GtkTextIter *iter);
+
+void     gtk_text_iter_set_offset         (GtkTextIter *iter,
+                                           gint         char_offset);
+void     gtk_text_iter_set_line           (GtkTextIter *iter,
+                                           gint         line_number);
+void     gtk_text_iter_set_line_offset    (GtkTextIter *iter,
+                                           gint         char_on_line);
+void     gtk_text_iter_forward_to_end     (GtkTextIter *iter);
+gboolean gtk_text_iter_forward_to_newline (GtkTextIter *iter);
 
 /* returns TRUE if a toggle was found; NULL for the tag pointer
    means "any tag toggle", otherwise the next toggle of the
    specified tag is located. */
-gboolean gtk_text_iter_forward_find_tag_toggle (GtkTextIter *iter,
-                                                 GtkTextTag  *tag);
+gboolean gtk_text_iter_forward_to_tag_toggle (GtkTextIter *iter,
+                                              GtkTextTag  *tag);
 
-gboolean gtk_text_iter_backward_find_tag_toggle (GtkTextIter *iter,
-                                                  GtkTextTag  *tag);
+gboolean gtk_text_iter_backward_to_tag_toggle (GtkTextIter *iter,
+                                               GtkTextTag  *tag);
 
-typedef gboolean (* GtkTextViewCharPredicate) (gunichar ch, gpointer user_data);
+typedef gboolean (* GtkTextCharPredicate) (gunichar ch, gpointer user_data);
 
 gboolean gtk_text_iter_forward_find_char      (GtkTextIter *iter,
-                                              GtkTextViewCharPredicate pred,
+                                              GtkTextCharPredicate pred,
                                               gpointer user_data);
 
 gboolean gtk_text_iter_backward_find_char     (GtkTextIter *iter,
-                                              GtkTextViewCharPredicate pred,
+                                              GtkTextCharPredicate pred,
                                               gpointer user_data);
 
+gboolean gtk_text_iter_forward_search         (GtkTextIter *iter,
+                                               const char  *str,
+                                               gboolean visible_only,
+                                               gboolean slice);
+
+gboolean gtk_text_iter_backward_search        (GtkTextIter *iter,
+                                               const char  *str,
+                                               gboolean visible_only,
+                                               gboolean slice);
+
 /*
  * Comparisons
  */
 gboolean gtk_text_iter_equal           (const GtkTextIter *lhs,
-                                         const GtkTextIter *rhs);
+                                        const GtkTextIter *rhs);
 gint     gtk_text_iter_compare         (const GtkTextIter *lhs,
-                                         const GtkTextIter *rhs);
+                                        const GtkTextIter *rhs);
 gboolean gtk_text_iter_in_region       (const GtkTextIter *iter,
-                                         const GtkTextIter *start,
-                                         const GtkTextIter *end);
+                                        const GtkTextIter *start,
+                                        const GtkTextIter *end);
 
 /* Put these two in ascending order */
 void     gtk_text_iter_reorder         (GtkTextIter *first,
index 6a23a3e8f9c926bea01a70da344e9d5f8019e4b6..0d9104d3e16d445fdb0dfc1830df6e98ac189eb9 100644 (file)
@@ -7,10 +7,13 @@
 extern "C" {
 #endif /* __cplusplus */
 
+#include <gtk/gtktextiter.h>
+#include <gtk/gtktextbtree.h>
+
 GtkTextLineSegment *gtk_text_iter_get_indexable_segment(const GtkTextIter *iter);
 GtkTextLineSegment *gtk_text_iter_get_any_segment(const GtkTextIter *iter);
 
-GtkTextLine *gtk_text_iter_get_line(const GtkTextIter *iter);
+GtkTextLine *gtk_text_iter_get_text_line(const GtkTextIter *iter);
 
 GtkTextBTree *gtk_text_iter_get_btree(const GtkTextIter *iter);
 
index 737a83e3bfad7240a68dbbf348d86bf282350d7e..1fa6c30528471804f4357581cd233416edf900fe 100644 (file)
@@ -246,7 +246,8 @@ gtk_text_layout_set_buffer (GtkTextLayout *layout,
   
   if (layout->buffer)
     {
-      gtk_text_btree_remove_view (layout->buffer->tree, layout);
+      gtk_text_btree_remove_view (_gtk_text_buffer_get_btree (layout->buffer),
+                                  layout);
       
       gtk_object_unref (GTK_OBJECT (layout->buffer));
       layout->buffer = NULL;
@@ -259,7 +260,7 @@ gtk_text_layout_set_buffer (GtkTextLayout *layout,
       gtk_object_sink (GTK_OBJECT (buffer));
       gtk_object_ref (GTK_OBJECT (buffer));
 
-      gtk_text_btree_add_view (buffer->tree, layout);
+      gtk_text_btree_add_view (_gtk_text_buffer_get_btree (buffer), layout);
     }
 }
 
@@ -337,7 +338,8 @@ gtk_text_layout_get_size (GtkTextLayout *layout,
   
   g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
   
-  gtk_text_btree_get_view_size (layout->buffer->tree, layout,
+  gtk_text_btree_get_view_size (_gtk_text_buffer_get_btree (layout->buffer),
+                                layout,
                                 &w, &h);
 
   layout->width = w;
@@ -419,7 +421,9 @@ gtk_text_layout_get_lines (GtkTextLayout *layout,
 
   retval = NULL;
   
-  first_btree_line = gtk_text_btree_find_line_by_y (layout->buffer->tree, layout, top_y, first_line_y);
+  first_btree_line =
+    gtk_text_btree_find_line_by_y (_gtk_text_buffer_get_btree (layout->buffer),
+                                   layout, top_y, first_line_y);
   if (first_btree_line == NULL)
     {
       g_assert (top_y > 0);
@@ -428,11 +432,15 @@ gtk_text_layout_get_lines (GtkTextLayout *layout,
     }
   
   /* -1 since bottom_y is one past */
-  last_btree_line = gtk_text_btree_find_line_by_y (layout->buffer->tree, layout, bottom_y - 1, NULL);
+  last_btree_line =
+    gtk_text_btree_find_line_by_y (_gtk_text_buffer_get_btree (layout->buffer),
+                                   layout, bottom_y - 1, NULL);
 
   if (!last_btree_line)
-    last_btree_line = gtk_text_btree_get_line (layout->buffer->tree,
-                                               gtk_text_btree_line_count (layout->buffer->tree) - 1, NULL);
+    last_btree_line =
+      gtk_text_btree_get_line (_gtk_text_buffer_get_btree (layout->buffer),
+                               gtk_text_btree_line_count (_gtk_text_buffer_get_btree (layout->buffer)) - 1,
+                               NULL);
 
   {
     GtkTextLineData *ld = gtk_text_line_get_data (last_btree_line, layout);
@@ -528,8 +536,8 @@ gtk_text_layout_real_invalidate (GtkTextLayout *layout,
   gtk_text_view_index_spew (end_index, "invalidate end");
 #endif
   
-  last_line = gtk_text_iter_get_line (end);
-  line = gtk_text_iter_get_line (start);
+  last_line = gtk_text_iter_get_text_line (end);
+  line = gtk_text_iter_get_text_line (start);
 
   while (TRUE)
     {
@@ -588,7 +596,8 @@ gtk_text_layout_is_valid (GtkTextLayout *layout)
   g_return_val_if_fail (layout != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_TEXT_LAYOUT (layout), FALSE);
   
-  return gtk_text_btree_is_valid (layout->buffer->tree, layout);
+  return gtk_text_btree_is_valid (_gtk_text_buffer_get_btree (layout->buffer),
+                                  layout);
 }
 
 /**
@@ -630,7 +639,7 @@ gtk_text_layout_validate_yrange (GtkTextLayout *layout,
   
   /* Validate backwards from the anchor line to y0
    */
-  line = gtk_text_iter_get_line (anchor);
+  line = gtk_text_iter_get_text_line (anchor);
   seen = 0;
   while (line && seen < -y0)
     {
@@ -639,7 +648,8 @@ gtk_text_layout_validate_yrange (GtkTextLayout *layout,
        {
          gint old_height = line_data ? line_data->height : 0;
          
-         gtk_text_btree_validate_line (layout->buffer->tree, line, layout);
+         gtk_text_btree_validate_line (_gtk_text_buffer_get_btree (layout->buffer),
+                                        line, layout);
          line_data = gtk_text_line_get_data (line, layout);
 
          delta_height += line_data->height - old_height;
@@ -658,7 +668,7 @@ gtk_text_layout_validate_yrange (GtkTextLayout *layout,
     }
 
   /* Validate forwards to y1 */
-  line = gtk_text_iter_get_line (anchor);
+  line = gtk_text_iter_get_text_line (anchor);
   seen = 0;
   while (line && seen < y1)
     {
@@ -667,7 +677,8 @@ gtk_text_layout_validate_yrange (GtkTextLayout *layout,
        {
          gint old_height = line_data ? line_data->height : 0;
          
-         gtk_text_btree_validate_line (layout->buffer->tree, line, layout);
+         gtk_text_btree_validate_line (_gtk_text_buffer_get_btree (layout->buffer),
+                                        line, layout);
          line_data = gtk_text_line_get_data (line, layout);
 
          delta_height += line_data->height - old_height;
@@ -689,7 +700,9 @@ gtk_text_layout_validate_yrange (GtkTextLayout *layout,
    */
   if (first_line)
     {
-      gint line_top = gtk_text_btree_find_line_top (layout->buffer->tree, first_line, layout);            
+      gint line_top =
+        gtk_text_btree_find_line_top (_gtk_text_buffer_get_btree (layout->buffer),
+                                      first_line, layout);            
       
       gtk_text_layout_changed (layout,
                               line_top,
@@ -717,7 +730,8 @@ gtk_text_layout_validate (GtkTextLayout *layout,
   g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
   
   while (max_pixels > 0 &&
-        gtk_text_btree_validate (layout->buffer->tree, layout,  max_pixels,
+        gtk_text_btree_validate (_gtk_text_buffer_get_btree (layout->buffer),
+                                  layout,  max_pixels,
                                  &y, &old_height, &new_height))
     {
       max_pixels -= new_height;
@@ -859,17 +873,18 @@ totally_invisible_line (GtkTextLayout *layout,
   int bytes = 0;
   
   /* If we have a cached style, then we know it does actually apply
-     and we can just see if it is elided. */
+     and we can just see if it is invisible. */
   if (layout->one_style_cache &&
-      !layout->one_style_cache->elide)
+      !layout->one_style_cache->invisible)
     return FALSE;
   /* Without the cache, we check if the first char is visible, if so
      we are partially visible.  Note that we have to check this since
-     we don't know the current elided/nonelided toggle state; this
+     we don't know the current invisible/noninvisible toggle state; this
      function can use the whole btree to get it right. */
   else
     {
-      gtk_text_btree_get_iter_at_line(layout->buffer->tree, iter, line, 0);
+      gtk_text_btree_get_iter_at_line(_gtk_text_buffer_get_btree (layout->buffer),
+                                      iter, line, 0);
       
       if (!gtk_text_btree_char_is_invisible (iter))
        return FALSE;
@@ -886,16 +901,16 @@ totally_invisible_line (GtkTextLayout *layout,
       /* Note that these two tests can cause us to bail out
          when we shouldn't, because a higher-priority tag
          may override these settings. However the important
-         thing is to only elide really-elided lines, rather
-         than to elide all really-elided lines. */
+         thing is to only invisible really-invisible lines, rather
+         than to invisible all really-invisible lines. */
       
       else if (seg->type == &gtk_text_toggle_on_type)
         {
           invalidate_cached_style (layout);
           
           /* Bail out if an elision-unsetting tag begins */
-          if (seg->body.toggle.info->tag->elide_set &&
-              !seg->body.toggle.info->tag->values->elide)
+          if (seg->body.toggle.info->tag->invisible_set &&
+              !seg->body.toggle.info->tag->values->invisible)
             break;
         }
       else if (seg->type == &gtk_text_toggle_off_type)
@@ -903,8 +918,8 @@ totally_invisible_line (GtkTextLayout *layout,
           invalidate_cached_style (layout);
           
           /* Bail out if an elision-setting tag ends */
-          if (seg->body.toggle.info->tag->elide_set &&
-              seg->body.toggle.info->tag->values->elide)
+          if (seg->body.toggle.info->tag->invisible_set &&
+              seg->body.toggle.info->tag->values->invisible)
             break;
         }
 
@@ -1135,7 +1150,8 @@ add_cursor (GtkTextLayout      *layout,
 
   /* Hide insertion cursor when we have a selection
    */
-  if (gtk_text_btree_mark_is_insert (layout->buffer->tree, (GtkTextMark*)seg) &&
+  if (gtk_text_btree_mark_is_insert (_gtk_text_buffer_get_btree (layout->buffer),
+                                     (GtkTextMark*)seg) &&
       gtk_text_buffer_get_selection_bounds (layout->buffer, &selection_start, &selection_end))
     return;
   
@@ -1205,7 +1221,8 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
   display->size_only = size_only;
   display->line = line;
 
-  gtk_text_btree_get_iter_at_line (layout->buffer->tree, &iter, line, 0);
+  gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
+                                   &iter, line, 0);
   
   /* Special-case optimization for completely
    * invisible lines; makes it faster to deal
@@ -1230,7 +1247,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
       if (seg->type == &gtk_text_char_type ||
          seg->type == &gtk_text_pixmap_type)
         {
-         gtk_text_btree_get_iter_at_line (layout->buffer->tree,
+         gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
                                           &iter, line,
                                           byte_offset);
          style = get_style (layout, &iter);
@@ -1246,12 +1263,12 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
              para_values_set = TRUE;
            }
 
-          /* First see if the chunk is elided, and ignore it if so. Tk
+          /* First see if the chunk is invisible, and ignore it if so. Tk
           * looked at tabs, wrap mode, etc. before doing this, but
           * that made no sense to me, so I am just skipping the
-          * elided chunks
+          * invisible chunks
           */
-          if (!style->elide)
+          if (!style->invisible)
             {
              if (seg->type == &gtk_text_char_type)
                {
@@ -1420,13 +1437,16 @@ get_line_at_y (GtkTextLayout *layout,
   if (y > layout->height)
     y = layout->height;
   
-  *line = gtk_text_btree_find_line_by_y (layout->buffer->tree, layout, y, line_top);
+  *line = gtk_text_btree_find_line_by_y (_gtk_text_buffer_get_btree (layout->buffer),
+                                         layout, y, line_top);
   if (*line == NULL)
     {
-      *line = gtk_text_btree_get_line (layout->buffer->tree,
-                                      gtk_text_btree_line_count (layout->buffer->tree) - 1, NULL);
+      *line = gtk_text_btree_get_line (_gtk_text_buffer_get_btree (layout->buffer),
+                                      gtk_text_btree_line_count (_gtk_text_buffer_get_btree (layout->buffer)) - 1, NULL);
       if (line_top)
-       *line_top = gtk_text_btree_find_line_top (layout->buffer->tree, *line, layout);      
+       *line_top =
+          gtk_text_btree_find_line_top (_gtk_text_buffer_get_btree (layout->buffer),
+                                        *line, layout);      
     }
 }
 
@@ -1453,7 +1473,8 @@ gtk_text_layout_get_line_at_y (GtkTextLayout *layout,
   g_return_if_fail (target_iter != NULL);
 
   get_line_at_y (layout, y, &line, line_top);
-  gtk_text_btree_get_iter_at_line (layout->buffer->tree, target_iter, line, 0);
+  gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
+                                   target_iter, line, 0);
 }
 
 void
@@ -1496,12 +1517,12 @@ gtk_text_layout_get_iter_at_pixel (GtkTextLayout *layout,
       trailing = 0;
     }
 
-  gtk_text_btree_get_iter_at_line (layout->buffer->tree,
+  gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
                                    target_iter,
                                    line, byte_index);
 
   while (trailing--)
-    gtk_text_iter_forward_char (target_iter);
+    gtk_text_iter_next_char (target_iter);
   
   gtk_text_layout_free_line_display (layout, display);
 }
@@ -1538,12 +1559,13 @@ gtk_text_layout_get_cursor_locations (GtkTextLayout  *layout,
   g_return_if_fail (layout != NULL);
   g_return_if_fail (iter != NULL);
   
-  line = gtk_text_iter_get_line (iter);
-  line_top = gtk_text_btree_find_line_top (layout->buffer->tree, line, layout);
+  line = gtk_text_iter_get_text_line (iter);
+  line_top = gtk_text_btree_find_line_top (_gtk_text_buffer_get_btree (layout->buffer),
+                                           line, layout);
 
   display = gtk_text_layout_get_line_display (layout, line, FALSE);
 
-  pango_layout_get_cursor_pos (display->layout, gtk_text_iter_get_line_byte (iter),
+  pango_layout_get_cursor_pos (display->layout, gtk_text_iter_get_line_index (iter),
                               strong_pos ? &pango_strong_pos : NULL,
                               weak_pos ? &pango_weak_pos : NULL);
 
@@ -1583,10 +1605,11 @@ gtk_text_layout_get_line_y (GtkTextLayout     *layout,
   GtkTextLine *line;
   
   g_return_val_if_fail (GTK_IS_TEXT_LAYOUT (layout), 0);
-  g_return_val_if_fail (gtk_text_iter_get_btree (iter) == layout->buffer->tree, 0);
+  g_return_val_if_fail (gtk_text_iter_get_btree (iter) == _gtk_text_buffer_get_btree (layout->buffer), 0);
   
-  line = gtk_text_iter_get_line (iter);
-  return gtk_text_btree_find_line_top (layout->buffer->tree, line, layout);
+  line = gtk_text_iter_get_text_line (iter);
+  return gtk_text_btree_find_line_top (_gtk_text_buffer_get_btree (layout->buffer),
+                                       line, layout);
 }
 
 void
@@ -1601,11 +1624,11 @@ gtk_text_layout_get_iter_location (GtkTextLayout     *layout,
   gint byte_index;
   
   g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
-  g_return_if_fail (gtk_text_iter_get_btree (iter) == layout->buffer->tree);
+  g_return_if_fail (gtk_text_iter_get_btree (iter) == _gtk_text_buffer_get_btree (layout->buffer));
   g_return_if_fail (rect != NULL);
   
   tree = gtk_text_iter_get_btree (iter);
-  line = gtk_text_iter_get_line (iter);
+  line = gtk_text_iter_get_text_line (iter);
 
   display = gtk_text_layout_get_line_display (layout, line, FALSE);
 
@@ -1628,8 +1651,8 @@ gtk_text_layout_get_iter_location (GtkTextLayout     *layout,
     }
   else
     {
-      byte_index = gtk_text_iter_get_line_byte (iter);
-  
+      byte_index = gtk_text_iter_get_line_index (iter);
+
       pango_layout_index_to_pos (display->layout, byte_index, &pango_rect);
       
       rect->x = display->x_offset + pango_rect.x / PANGO_SCALE;
@@ -1655,12 +1678,17 @@ find_display_line_below (GtkTextLayout *layout,
   gint line_top;
   gint found_byte = 0;
   
-  line = gtk_text_btree_find_line_by_y (layout->buffer->tree, layout, y, &line_top);
+  line = gtk_text_btree_find_line_by_y (_gtk_text_buffer_get_btree (layout->buffer),
+                                        layout, y, &line_top);
   if (!line)
     {
-      line = gtk_text_btree_get_line (layout->buffer->tree,
-                                     gtk_text_btree_line_count (layout->buffer->tree) - 1, NULL);
-      line_top = gtk_text_btree_find_line_top (layout->buffer->tree, line, layout);
+      line =
+        gtk_text_btree_get_line (_gtk_text_buffer_get_btree (layout->buffer),
+                                 gtk_text_btree_line_count (_gtk_text_buffer_get_btree (layout->buffer)) - 1,
+                                 NULL);
+      line_top =
+        gtk_text_btree_find_line_top (_gtk_text_buffer_get_btree (layout->buffer),
+                                      line, layout);
     }
 
   while (line && !found_line)
@@ -1700,7 +1728,8 @@ find_display_line_below (GtkTextLayout *layout,
       line = next;
     }
   
-  gtk_text_btree_get_iter_at_line (layout->buffer->tree, iter, found_line, found_byte);
+  gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
+                                   iter, found_line, found_byte);
 }
   
 /* Find the iter for the logical beginning of the last display line whose
@@ -1717,12 +1746,12 @@ find_display_line_above (GtkTextLayout *layout,
   gint line_top;
   gint found_byte = 0;
   
-  line = gtk_text_btree_find_line_by_y (layout->buffer->tree, layout, y, &line_top);
+  line = gtk_text_btree_find_line_by_y (_gtk_text_buffer_get_btree (layout->buffer), layout, y, &line_top);
   if (!line)
     {
-      line = gtk_text_btree_get_line (layout->buffer->tree,
-                                     gtk_text_btree_line_count (layout->buffer->tree) - 1, NULL);
-      line_top = gtk_text_btree_find_line_top (layout->buffer->tree, line, layout);
+      line = gtk_text_btree_get_line (_gtk_text_buffer_get_btree (layout->buffer),
+                                     gtk_text_btree_line_count (_gtk_text_buffer_get_btree (layout->buffer)) - 1, NULL);
+      line_top = gtk_text_btree_find_line_top (_gtk_text_buffer_get_btree (layout->buffer), line, layout);
     }
 
   while (line && !found_line)
@@ -1766,9 +1795,10 @@ find_display_line_above (GtkTextLayout *layout,
     }
 
   if (found_line)
-    gtk_text_btree_get_iter_at_line (layout->buffer->tree, iter, found_line, found_byte);
+    gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
+                                     iter, found_line, found_byte);
   else
-    gtk_text_buffer_get_iter_at_char (layout->buffer, iter, 0);
+    gtk_text_buffer_get_iter_at_offset (layout->buffer, iter, 0);
 }
   
 /**
@@ -1839,8 +1869,8 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
   g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
   g_return_if_fail (iter != NULL);
   
-  line = gtk_text_iter_get_line (iter);
-  line_byte = gtk_text_iter_get_line_byte (iter);
+  line = gtk_text_iter_get_text_line (iter);
+  line_byte = gtk_text_iter_get_line_index (iter);
   
   display = gtk_text_layout_get_line_display (layout, line, FALSE);
 
@@ -1868,11 +1898,11 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
              byte_offset += layout_line->length;
            }
 
-         gtk_text_btree_get_iter_at_line (layout->buffer->tree,
+         gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
                                           iter, prev_line, byte_offset);
        }
       else
-       gtk_text_btree_get_iter_at_line (layout->buffer->tree,
+       gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
                                         iter, line, 0);
     }
   else
@@ -1887,7 +1917,7 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
 
          if (line_byte < byte_offset + layout_line->length || !tmp_list->next)
            {
-             gtk_text_btree_get_iter_at_line (layout->buffer->tree,
+             gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
                                               iter, line, prev_offset);
              break;
            }
@@ -1925,8 +1955,8 @@ gtk_text_layout_move_iter_to_next_line (GtkTextLayout *layout,
   g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
   g_return_if_fail (iter != NULL);
   
-  line = gtk_text_iter_get_line (iter);
-  line_byte = gtk_text_iter_get_line_byte (iter);
+  line = gtk_text_iter_get_text_line (iter);
+  line_byte = gtk_text_iter_get_line_index (iter);
   
   while (line && !found_after)
     {
@@ -1942,7 +1972,7 @@ gtk_text_layout_move_iter_to_next_line (GtkTextLayout *layout,
 
          if (found)
            {
-             gtk_text_btree_get_iter_at_line (layout->buffer->tree,
+             gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
                                               iter, line,
                                               byte_offset);
              found_after = TRUE;
@@ -1985,8 +2015,8 @@ gtk_text_layout_move_iter_to_x (GtkTextLayout *layout,
   g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
   g_return_if_fail (iter != NULL);
   
-  line = gtk_text_iter_get_line (iter);
-  line_byte = gtk_text_iter_get_line_byte (iter);
+  line = gtk_text_iter_get_text_line (iter);
+  line_byte = gtk_text_iter_get_line_index (iter);
   
   display = gtk_text_layout_get_line_display (layout, line, FALSE);
 
@@ -2024,12 +2054,12 @@ gtk_text_layout_move_iter_to_x (GtkTextLayout *layout,
                                        x * PANGO_SCALE - x_offset,
                                        &byte_index, &trailing);
 
-         gtk_text_btree_get_iter_at_line (layout->buffer->tree,
+         gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
                                           iter,
                                           line, byte_index);
          
          while (trailing--)
-           gtk_text_iter_forward_char (iter);
+           gtk_text_iter_next_char (iter);
 
          break;
        }
@@ -2070,9 +2100,10 @@ gtk_text_layout_move_iter_visually (GtkTextLayout *layout,
   
   while (count != 0)
     {
-      GtkTextLine *line = gtk_text_iter_get_line (iter);
-      gint line_byte = gtk_text_iter_get_line_byte (iter);
+      GtkTextLine *line = gtk_text_iter_get_text_line (iter);
+      gint line_byte = gtk_text_iter_get_line_index (iter);
       GtkTextLineDisplay *display = gtk_text_layout_get_line_display (layout, line, FALSE);
+
       int byte_count = gtk_text_line_byte_count (line);
       
       int new_index;
@@ -2109,11 +2140,11 @@ gtk_text_layout_move_iter_visually (GtkTextLayout *layout,
          new_index = 0;
        }
 
-      gtk_text_btree_get_iter_at_line (layout->buffer->tree,
+      gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
                                       iter,
                                       line, new_index);
       while (new_trailing--)
-       gtk_text_iter_forward_char (iter);
+       gtk_text_iter_next_char (iter);
     }
 
 }
index 200b13e128ac8627491c0de8c08ab193aca09034..3510e032a7989b5b0d684eb1953d2cd5da483eaf 100644 (file)
@@ -1,10 +1,6 @@
 #ifndef GTK_TEXT_LAYOUT_H
 #define GTK_TEXT_LAYOUT_H
 
-#include <gtk/gtktextbuffer.h>
-#include <gtk/gtktextiter.h>
-#include <gtk/gtktextbtree.h>
-
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
@@ -16,6 +12,15 @@ extern "C" {
  * to use it. 
  */
 
+#include <gtk/gtktextbuffer.h>
+#include <gtk/gtktextiter.h>
+
+/* forward declarations that have to be here to avoid including
+ * gtktextbtree.h
+ */
+typedef struct _GtkTextLine     GtkTextLine;
+typedef struct _GtkTextLineData GtkTextLineData;
+
 #define GTK_TYPE_TEXT_LAYOUT             (gtk_text_layout_get_type())
 #define GTK_TEXT_LAYOUT(obj)             (GTK_CHECK_CAST ((obj), GTK_TYPE_TEXT_LAYOUT, GtkTextLayout))
 #define GTK_TEXT_LAYOUT_CLASS(klass)     (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_TEXT_LAYOUT, GtkTextLayoutClass))
@@ -23,6 +28,7 @@ extern "C" {
 #define GTK_IS_TEXT_LAYOUT_CLASS(klass)  (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_TEXT_LAYOUT))
 #define GTK_TEXT_LAYOUT_GET_CLASS(obj)   (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_TEXT_LAYOUT, GtkTextLayoutClass))
 
+typedef struct _GtkTextLayout      GtkTextLayout;
 typedef struct _GtkTextLayoutClass GtkTextLayoutClass;
 typedef struct _GtkTextLineDisplay GtkTextLineDisplay;
 typedef struct _GtkTextCursorDisplay GtkTextCursorDisplay;
index 72cb4f1bab9f16d9d33c17309d367d0652a07ece..f85ef0a6ba6cdba1ac18703852c34229338faf60 100644 (file)
@@ -35,6 +35,41 @@ gtk_text_mark_get_name (GtkTextMark *mark)
   return g_strdup (seg->body.mark.name);
 }
 
+
+GtkTextMark *
+gtk_text_mark_ref (GtkTextMark *mark)
+{
+  GtkTextLineSegment *seg;
+
+  seg = (GtkTextLineSegment*)mark;
+
+  mark_segment_ref (seg);
+
+  return mark;
+}
+
+void
+gtk_text_mark_unref (GtkTextMark *mark)
+{
+  GtkTextLineSegment *seg;
+
+  seg = (GtkTextLineSegment*)mark;
+  
+  mark_segment_unref (seg);
+}
+
+gboolean
+gtk_text_mark_deleted (GtkTextMark *mark)
+{
+  GtkTextLineSegment *seg;
+  
+  g_return_val_if_fail (mark != NULL, FALSE);
+
+  seg = (GtkTextLineSegment*)mark;
+  
+  return seg->body.mark.tree == NULL;
+}
+
 /*
  * Macro that determines the size of a mark segment:
  */
index 9079e11e4b4ac32715e2258569dc962e3e64e26e..19cb7a8df0c04234d53efb297ddb2e2b9f6b2c26 100644 (file)
@@ -10,12 +10,17 @@ extern "C" {
 typedef struct _GtkTextMark GtkTextMark;
 
 void gtk_text_mark_set_visible (GtkTextMark *mark,
-                                 gboolean setting);
+                                gboolean setting);
 
 gboolean gtk_text_mark_is_visible (GtkTextMark *mark);
 /* Temporarily commented out until memory management behavior is figured out */
 /* char *   gtk_text_mark_get_name   (GtkTextMark *mark); */
 
+GtkTextMark *gtk_text_mark_ref (GtkTextMark *mark);
+void         gtk_text_mark_unref (GtkTextMark *mark);
+
+gboolean   gtk_text_mark_deleted (GtkTextMark *mark);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 08b64fac003a6c22cef600ba1cdf6b22823ac7ac..07ebc2aeda8ec099c6e132174e966e6fdb9ce2a6 100644 (file)
@@ -1,12 +1,13 @@
 #ifndef GTK_TEXT_MARK_PRIVATE_H
 #define GTK_TEXT_MARK_PRIVATE_H
 
-#include <gtk/gtktexttypes.h>
-
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
 
+#include <gtk/gtktexttypes.h>
+#include <gtk/gtktextlayout.h>
+
 #define GTK_IS_TEXT_MARK(mark) (((GtkTextLineSegment*)mark)->type == &gtk_text_left_mark_type || \
                                 ((GtkTextLineSegment*)mark)->type == &gtk_text_right_mark_type)
 
index 38e905865b69f387725a0a66e9b7d0db2a9de9a1..11313e3bb133a12c38fe091dad40bbaa2171b7b0 100644 (file)
@@ -97,10 +97,10 @@ gtk_text_line_segment_split(const GtkTextIter *iter)
   GtkTextLine *line;
   int count;
 
-  line = gtk_text_iter_get_line(iter);
+  line = gtk_text_iter_get_text_line(iter);
   tree = gtk_text_iter_get_btree(iter);
   
-  count = gtk_text_iter_get_line_byte(iter);
+  count = gtk_text_iter_get_line_index(iter);
   
   prev = NULL;
   seg = line->segments;
index f39f7124ec21238b5560d7d6bb2dd00da6a0c71d..bfecac98bc8a0b8bd365c02b0c9751e8f9d3463e 100644 (file)
@@ -52,6 +52,7 @@
 #include "gtktexttypes.h"
 #include "gtktexttagtable.h"
 #include "gtksignal.h"
+#include "gtkmain.h"
 
 #include <stdlib.h>
 
@@ -331,7 +332,7 @@ gtk_text_tag_destroy (GtkObject *object)
   g_assert(!tkxt_tag->values->realized);
   
   if (tkxt_tag->table)
-    gtk_text_tag_table_remove(tkxt_tag->table, tkxt_tag->name);
+    gtk_text_tag_table_remove(tkxt_tag->table, tkxt_tag);
 
   g_assert(tkxt_tag->table == NULL);
   
@@ -915,17 +916,22 @@ typedef struct {
 } DeltaData;
 
 static void
-delta_priority_foreach(gpointer key, gpointer value, gpointer user_data)
+delta_priority_foreach(GtkTextTag *tag, gpointer user_data)
 {
-  GtkTextTag *tag;
   DeltaData *dd = user_data;
-  
-  tag = GTK_TEXT_TAG(value);
 
   if (tag->priority >= dd->low && tag->priority <= dd->high)
     tag->priority += dd->delta;
 }
 
+gint
+gtk_text_tag_get_priority (GtkTextTag *tag)
+{
+  g_return_val_if_fail(GTK_IS_TEXT_TAG(tag), 0);
+
+  return tag->priority;
+}
+
 void
 gtk_text_tag_set_priority(GtkTextTag *tag,
                            gint priority)
@@ -951,7 +957,7 @@ gtk_text_tag_set_priority(GtkTextTag *tag,
     }
 
     gtk_text_tag_table_foreach(tag->table, delta_priority_foreach,
-                                &dd);
+                               &dd);
     
     tag->priority = priority;
 }
@@ -1287,8 +1293,8 @@ gtk_text_style_values_fill_from_tags(GtkTextStyleValues *dest,
       if (tag->overstrike_set)
         dest->appearance.overstrike = vals->appearance.overstrike;
 
-      if (tag->elide_set)
-        dest->elide = vals->elide;
+      if (tag->invisible_set)
+        dest->invisible = vals->invisible;
 
       if (tag->editable_set)
         dest->editable = vals->editable;
index 7fac2e185fa89ee0f7fabbd61f1f868867497c90..ef5ee94880ae53bfa68c135b52d511f0a1227332 100644 (file)
@@ -77,7 +77,7 @@ struct _GtkTextTag {
   guint underline_set : 1;
   guint wrap_mode_set : 1;
   guint bg_full_height_set : 1;
-  guint elide_set : 1;
+  guint invisible_set : 1;
   guint editable_set : 1;
   guint language_set : 1;
   guint pad1 : 1;
@@ -96,6 +96,7 @@ struct _GtkTextTagClass {
 
 GtkType      gtk_text_tag_get_type     (void);
 GtkTextTag  *gtk_text_tag_new          (const gchar       *name);
+gint         gtk_text_tag_get_priority (GtkTextTag        *tag);
 void         gtk_text_tag_set_priority (GtkTextTag        *tag,
                                        gint               priority);
 gint         gtk_text_tag_event        (GtkTextTag        *tag,
@@ -103,6 +104,100 @@ gint         gtk_text_tag_event        (GtkTextTag        *tag,
                                        GdkEvent          *event,
                                        const GtkTextIter *iter);
 
+/*
+ * Style object created by folding a set of tags together
+ */
+
+typedef struct _GtkTextAppearance GtkTextAppearance;
+
+struct _GtkTextAppearance
+{
+  GdkColor bg_color;
+  GdkColor fg_color;
+  GdkBitmap *bg_stipple;
+  GdkBitmap *fg_stipple;
+
+  guint underline : 4;         /* PangoUnderline */
+  guint overstrike : 1;
+
+  /* Whether to use background-related values; this is irrelevant for
+   * the values struct when in a tag, but is used for the composite
+   * values struct; it's true if any of the tags being composited
+   * had background stuff set. */
+  guint draw_bg : 1;
+
+  /* This is only used when we are actually laying out and rendering
+   * a paragraph; not when a GtkTextAppearance is part of a
+   * GtkTextStyleValues.
+   */
+  guint inside_selection : 1;
+};
+
+struct _GtkTextStyleValues
+{
+  guint refcount;
+
+  GtkTextAppearance appearance;
+  
+  gint border_width;
+  GtkShadowType relief;
+  GtkJustification justify;
+  GtkTextDirection direction;
+  
+  PangoFontDescription *font_desc;
+  
+  /* lMargin1 */
+  gint left_margin;
+  
+  /* lMargin2 */
+  gint left_wrapped_line_margin;
+
+  /* super/subscript offset, can be negative */
+  gint offset;
+  
+  gint right_margin;
+
+  gint pixels_above_lines;
+
+  gint pixels_below_lines;
+
+  gint pixels_inside_wrap;
+
+  GtkTextTabArray *tab_array;
+  
+  GtkWrapMode wrap_mode;       /* How to handle wrap-around for this tag.
+                                * Must be GTK_WRAPMODE_CHAR,
+                                * GTK_WRAPMODE_NONE, GTK_WRAPMODE_WORD
+                                 */
+
+  gchar *language;
+  
+  /* hide the text  */
+  guint invisible : 1;
+
+  /* Background is fit to full line height rather than
+   * baseline +/- ascent/descent (font height) */
+  guint bg_full_height : 1;
+  
+  /* can edit this text */
+  guint editable : 1;
+
+  /* colors are allocated etc. */
+  guint realized : 1;
+
+  guint pad1 : 1;
+  guint pad2 : 1;
+  guint pad3 : 1;
+  guint pad4 : 1;
+};
+
+GtkTextStyleValues *gtk_text_style_values_new       (void);
+void                gtk_text_style_values_copy      (GtkTextStyleValues *src,
+                                                     GtkTextStyleValues *dest);
+void                gtk_text_style_values_unref     (GtkTextStyleValues *values);
+void                gtk_text_style_values_ref       (GtkTextStyleValues *values);
+
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index c19ddf27541f5e7b442b32b2678a6014cc2f625f..d8ec06fe8a1d032183821dde006d45a0f91d640f 100644 (file)
@@ -13,99 +13,6 @@ void gtk_text_style_values_fill_from_tags (GtkTextStyleValues  *values,
 void gtk_text_tag_array_sort              (GtkTextTag         **tag_array_p,
                                            guint                len);
 
-/*
- * Style object created by folding a set of tags together
- */
-
-typedef struct _GtkTextAppearance GtkTextAppearance;
-
-struct _GtkTextAppearance
-{
-  GdkColor bg_color;
-  GdkColor fg_color;
-  GdkBitmap *bg_stipple;
-  GdkBitmap *fg_stipple;
-
-  guint underline : 4;         /* PangoUnderline */
-  guint overstrike : 1;
-
-  /* Whether to use background-related values; this is irrelevant for
-   * the values struct when in a tag, but is used for the composite
-   * values struct; it's true if any of the tags being composited
-   * had background stuff set. */
-  guint draw_bg : 1;
-
-  /* This is only used when we are actually laying out and rendering
-   * a paragraph; not when a GtkTextAppearance is part of a
-   * GtkTextStyleValues.
-   */
-  guint inside_selection : 1;
-};
-
-struct _GtkTextStyleValues
-{
-  guint refcount;
-
-  GtkTextAppearance appearance;
-  
-  gint border_width;
-  GtkShadowType relief;
-  GtkJustification justify;
-  GtkTextDirection direction;
-  
-  PangoFontDescription *font_desc;
-  
-  /* lMargin1 */
-  gint left_margin;
-  
-  /* lMargin2 */
-  gint left_wrapped_line_margin;
-
-  /* super/subscript offset, can be negative */
-  gint offset;
-  
-  gint right_margin;
-
-  gint pixels_above_lines;
-
-  gint pixels_below_lines;
-
-  gint pixels_inside_wrap;
-
-  GtkTextTabArray *tab_array;
-  
-  GtkWrapMode wrap_mode;       /* How to handle wrap-around for this tag.
-                                * Must be GTK_WRAPMODE_CHAR,
-                                * GTK_WRAPMODE_NONE, GTK_WRAPMODE_WORD
-                                 */
-
-  gchar *language;
-  
-  /* hide the text  */
-  guint elide : 1;
-
-  /* Background is fit to full line height rather than
-   * baseline +/- ascent/descent (font height) */
-  guint bg_full_height : 1;
-  
-  /* can edit this text */
-  guint editable : 1;
-
-  /* colors are allocated etc. */
-  guint realized : 1;
-
-  guint pad1 : 1;
-  guint pad2 : 1;
-  guint pad3 : 1;
-  guint pad4 : 1;
-};
-
-GtkTextStyleValues *gtk_text_style_values_new       (void);
-void                gtk_text_style_values_copy      (GtkTextStyleValues *src,
-                                                     GtkTextStyleValues *dest);
-void                gtk_text_style_values_unref     (GtkTextStyleValues *values);
-void                gtk_text_style_values_ref       (GtkTextStyleValues *values);
-
 /* ensure colors are allocated, etc. for drawing */
 void                gtk_text_style_values_realize   (GtkTextStyleValues *values,
                                                      GdkColormap        *cmap,
index b204c61b85c5f66078a061f4d621daff2c189a60..f79b34bfaa5c920f87742fa3ea04542f284377d9 100644 (file)
@@ -125,6 +125,12 @@ gtk_text_tag_table_destroy (GtkObject *object)
   (* GTK_OBJECT_CLASS(parent_class)->destroy) (object);
 }
 
+static void
+foreach_unref (GtkTextTag *tag, gpointer data)
+{
+  g_object_unref (G_OBJECT (tag));
+}
+
 static void
 gtk_text_tag_table_finalize (GObject *object)
 {
@@ -132,8 +138,11 @@ gtk_text_tag_table_finalize (GObject *object)
 
   table = GTK_TEXT_TAG_TABLE(object);
 
-  g_hash_table_destroy(table->hash);
+  gtk_text_tag_table_foreach (table, foreach_unref, NULL);
   
+  g_hash_table_destroy(table->hash);
+  g_slist_free (table->anonymous);
+
   (* G_OBJECT_CLASS(parent_class)->finalize) (object);
 }
 
@@ -174,14 +183,23 @@ gtk_text_tag_table_add(GtkTextTagTable *table, GtkTextTag *tag)
 {
   guint size;
   
-  g_return_if_fail(GTK_IS_TEXT_TAG_TABLE(table));
-  g_return_if_fail(GTK_IS_OBJECT(tag));
-  g_return_if_fail(g_hash_table_lookup(table->hash, tag->name) == NULL);
+  g_return_if_fail(GTK_IS_TEXT_TAG_TABLE (table));
+  g_return_if_fail(GTK_IS_TEXT_TAG (tag));
+  g_return_if_fail(tag->name == NULL ||
+                   g_hash_table_lookup(table->hash, tag->name) == NULL);
   g_return_if_fail(tag->table == NULL);
-  
+
   gtk_object_ref(GTK_OBJECT(tag));
   gtk_object_sink(GTK_OBJECT(tag));
-  g_hash_table_insert(table->hash, tag->name, tag);
+
+  if (tag->name)
+    g_hash_table_insert(table->hash, tag->name, tag);
+  else
+    {
+      table->anonymous = g_slist_prepend (table->anonymous, tag);
+      table->anon_count += 1;
+    }
+  
   tag->table = table;
 
   /* We get the highest tag priority, as the most-recently-added
@@ -204,19 +222,11 @@ gtk_text_tag_table_lookup(GtkTextTagTable *table, const gchar *name)
 }
 
 void
-gtk_text_tag_table_remove(GtkTextTagTable *table, const gchar *name)
+gtk_text_tag_table_remove(GtkTextTagTable *table, GtkTextTag *tag)
 {
-  GtkTextTag *tag;
-  
-  g_return_if_fail(GTK_IS_TEXT_TAG_TABLE(table));
-  g_return_if_fail(name != NULL);
-  
-  tag = g_hash_table_lookup(table->hash, name);
-
-  if (tag == NULL)
-    return;
-
-  g_return_if_fail(tag->table == table);
+  g_return_if_fail (GTK_IS_TEXT_TAG_TABLE(table));
+  g_return_if_fail (GTK_IS_TEXT_TAG (tag));
+  g_return_if_fail (tag->table == table);  
 
   /* Set ourselves to the highest priority; this means
      when we're removed, there won't be any gaps in the
@@ -224,23 +234,48 @@ gtk_text_tag_table_remove(GtkTextTagTable *table, const gchar *name)
   gtk_text_tag_set_priority(tag, gtk_text_tag_table_size(table) - 1);
   
   tag->table = NULL;
-  
-  g_hash_table_remove(table->hash, name);
 
+  if (tag->name)
+    g_hash_table_remove(table->hash, tag->name);
+  else
+    {
+      table->anonymous = g_slist_remove (table->anonymous, tag);
+      table->anon_count -= 1;
+    }
+  
   gtk_signal_emit(GTK_OBJECT(table), signals[TAG_REMOVED], tag);
 
   gtk_object_unref(GTK_OBJECT(tag));
 }
 
+struct ForeachData
+{
+  GtkTextTagTableForeach func;
+  gpointer data;
+};
+
+static void
+hash_foreach (gpointer key, gpointer value, gpointer data)
+{
+  struct ForeachData *fd = data;
+
+  (* fd->func) (value, fd->data);
+}
+
 void
-gtk_text_tag_table_foreach(GtkTextTagTable *table,
-                            GHFunc func,
-                            gpointer data)
+gtk_text_tag_table_foreach(GtkTextTagTable       *table,
+                           GtkTextTagTableForeach func,
+                           gpointer               data)
 {
+  struct ForeachData d;
+  
   g_return_if_fail(GTK_IS_TEXT_TAG_TABLE(table));
   g_return_if_fail(func != NULL);
 
-  g_hash_table_foreach(table->hash, func, data);
+  d.func = func;
+  d.data = data;
+  
+  g_hash_table_foreach(table->hash, hash_foreach, &d);
 }
 
 guint
@@ -248,5 +283,5 @@ gtk_text_tag_table_size(GtkTextTagTable *table)
 {
   g_return_val_if_fail(GTK_IS_TEXT_TAG_TABLE(table), 0);
 
-  return g_hash_table_size(table->hash);
+  return g_hash_table_size(table->hash) + table->anon_count;
 }
index fee66bd722b16751669eda89746e00bfc12b40c9..c85ec2f1aa5fe5e3f5057636afcefbb7e5146e91 100644 (file)
@@ -7,6 +7,10 @@
 extern "C" {
 #endif /* __cplusplus */
 
+#include <gtk/gtktexttag.h>
+
+typedef void (* GtkTextTagTableForeach) (GtkTextTag *tag, gpointer data);
+
 #define GTK_TYPE_TEXT_TAG_TABLE            (gtk_text_tag_table_get_type())
 #define GTK_TEXT_TAG_TABLE(obj)            (GTK_CHECK_CAST ((obj), GTK_TYPE_TEXT_TAG_TABLE, GtkTextTagTable))
 #define GTK_TEXT_TAG_TABLE_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_TEXT_TAG_TABLE, GtkTextTagTableClass))
@@ -20,6 +24,8 @@ struct _GtkTextTagTable {
   GtkObject parent_instance;
   
   GHashTable *hash;
+  GSList *anonymous;
+  gint anon_count;
 };
 
 struct _GtkTextTagTableClass {
@@ -33,17 +39,17 @@ struct _GtkTextTagTableClass {
 GtkType          gtk_text_tag_table_get_type (void);
 
 GtkTextTagTable *gtk_text_tag_table_new      (void);
-void             gtk_text_tag_table_add      (GtkTextTagTable *table,
-                                             GtkTextTag      *tag);
-GtkTextTag      *gtk_text_tag_table_lookup   (GtkTextTagTable *table,
-                                             const gchar     *name);
-void             gtk_text_tag_table_remove   (GtkTextTagTable *table,
-                                             const gchar     *name);
-void             gtk_text_tag_table_foreach  (GtkTextTagTable *table,
-                                             GHFunc           func,
-                                             gpointer         data);
-
-guint            gtk_text_tag_table_size     (GtkTextTagTable *table);
+void             gtk_text_tag_table_add      (GtkTextTagTable        *table,
+                                              GtkTextTag             *tag);
+void             gtk_text_tag_table_remove   (GtkTextTagTable        *table,
+                                              GtkTextTag             *tag);
+GtkTextTag      *gtk_text_tag_table_lookup   (GtkTextTagTable        *table,
+                                              const gchar            *name);
+void             gtk_text_tag_table_foreach  (GtkTextTagTable        *table,
+                                              GtkTextTagTableForeach  func,
+                                              gpointer                data);
+guint            gtk_text_tag_table_size     (GtkTextTagTable        *table);
+
 
 #ifdef __cplusplus
 }
index c9ba97df6bd3a8e2deecce3b475145b8459d99a7..0a05e0dac278ca4b4a0458b15fec354f90d5decd 100644 (file)
@@ -140,3 +140,92 @@ gtk_text_latin1_to_utf (const gchar *latin1, gint len)
 
 
 
+#include <iconv.h>
+#include <errno.h>
+#include <string.h>
+
+gchar*
+g_convert (const gchar *str,
+           gint         len,
+           const gchar *to_codeset,
+           const gchar *from_codeset,
+           gint        *bytes_converted)
+{
+  gchar *dest;
+  gchar *outp;
+  const gchar *p;
+  size_t inbytes_remaining;
+  size_t outbytes_remaining;
+  size_t err;
+  iconv_t cd;
+  size_t outbuf_size;
+  
+  g_return_val_if_fail (str != NULL, NULL);
+  g_return_val_if_fail (to_codeset != NULL, NULL);
+  g_return_val_if_fail (from_codeset != NULL, NULL);
+     
+  cd = iconv_open (to_codeset, from_codeset);
+
+  if (cd == (iconv_t) -1)
+    {
+      /* Something went wrong.  */
+      if (errno == EINVAL)
+        g_warning ("Conversion from character set `%s' to `%s' is not supported",
+                   from_codeset, to_codeset);
+      else
+        g_warning ("Failed to convert character set `%s' to `%s': %s",
+                   from_codeset, to_codeset, strerror (errno));
+
+      if (bytes_converted)
+        *bytes_converted = 0;
+      
+      return NULL;
+    }
+
+  if (len < 0)
+    len = strlen (str);
+
+  p = str;
+  inbytes_remaining = len;
+  outbuf_size = len + 1; /* + 1 for nul in case len == 1 */
+  outbytes_remaining = outbuf_size - 1; /* -1 for nul */
+  outp = dest = g_malloc (outbuf_size);
+
+ again:
+  
+  err = iconv (cd, &p, &inbytes_remaining, &outp, &outbytes_remaining);
+
+  if (err == (size_t) -1)
+    {
+      if (errno == E2BIG)
+        {
+          size_t used = outp - dest;
+          outbuf_size *= 2;
+          dest = g_realloc (dest, outbuf_size);
+
+          outp = dest + used;
+          outbytes_remaining = outbuf_size - used - 1; /* -1 for nul */
+
+          goto again;
+        }
+      else
+        g_warning ("iconv() failed: %s", strerror (errno));
+    }
+
+  *outp = '\0';
+  
+  if (iconv_close (cd) != 0)
+    g_warning ("Failed to close iconv() conversion descriptor: %s",
+               strerror (errno));
+
+  if (bytes_converted)
+    *bytes_converted = p - str;
+
+  if (p == str)
+    {
+      g_free (dest);
+      return NULL;
+    }
+  else
+    return dest;
+}
index 19d72a12091b5dfe5027793d86949b11e83a197f..ad8244854247f685f6e09b01a78117b0fef5cf64 100644 (file)
@@ -1,16 +1,16 @@
 #ifndef GTK_TEXT_TYPES_H
 #define GTK_TEXT_TYPES_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
 #include <glib.h>
 
 #include <gtk/gtktextbuffer.h>
 #include <gtk/gtktexttagprivate.h>
 
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
 
-typedef struct _GtkTextLine GtkTextLine;
 typedef struct _GtkTextCounter GtkTextCounter;
 typedef struct _GtkTextLineSegment GtkTextLineSegment;
 typedef struct _GtkTextLineSegmentClass GtkTextLineSegmentClass;
@@ -19,7 +19,6 @@ typedef struct _GtkTextViewSearch GtkTextViewSearch;
 typedef struct _GtkTextTab GtkTextTab;
 typedef struct _GtkTextViewStyle GtkTextViewStyle;
 typedef struct _GtkTextMarkBody GtkTextMarkBody;
-typedef struct _GtkTextLayout GtkTextLayout;
 
 /*
  * Search
@@ -126,6 +125,12 @@ gchar*   gtk_text_latin1_to_utf         (const gchar *latin1,
                                          gint         len);
 
 
+gchar*   g_convert (const gchar *str,
+                    gint         len,
+                    const gchar *to_codeset,
+                    const gchar *from_codeset,
+                    gint        *bytes_converted);
+       
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 7304f7302ac6c8bb8954d800732f17c1dfc00b9e..db87d9c16d1e51ecb4eb215c73e966b4d1f40cbd 100644 (file)
@@ -59,6 +59,8 @@
 #include "gtktextview.h"
 #include "gtkimmulticontext.h"
 #include "gdk/gdkkeysyms.h"
+#include "gtktexttypes.h"
+#include <string.h>
 
 enum {
   MOVE_INSERT,
@@ -219,6 +221,9 @@ static void gtk_text_view_set_virtual_cursor_pos (GtkTextView       *text_view,
                                                  gint               x,
                                                  gint               y);
 
+static GtkAdjustment* get_hadjustment            (GtkTextView       *text_view);
+static GtkAdjustment* get_vadjustment            (GtkTextView       *text_view);
+
 enum {
   TARGET_STRING,
   TARGET_TEXT,
@@ -427,22 +432,22 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
   
   /* Eventually we want to move by display lines, not paragraphs */
   add_move_insert_binding (binding_set, GDK_Up, 0,
-                          GTK_TEXT_MOVEMENT_LINE, -1);
+                          GTK_TEXT_MOVEMENT_WRAPPED_LINE, -1);
   
   add_move_insert_binding (binding_set, GDK_Down, 0,
-                          GTK_TEXT_MOVEMENT_LINE, 1);
+                          GTK_TEXT_MOVEMENT_WRAPPED_LINE, 1);
 
   add_move_insert_binding (binding_set, GDK_p, GDK_CONTROL_MASK,
-                          GTK_TEXT_MOVEMENT_LINE, -1);
+                          GTK_TEXT_MOVEMENT_WRAPPED_LINE, -1);
   
   add_move_insert_binding (binding_set, GDK_n, GDK_CONTROL_MASK,
-                          GTK_TEXT_MOVEMENT_LINE, 1);
+                          GTK_TEXT_MOVEMENT_WRAPPED_LINE, 1);
   
   add_move_insert_binding (binding_set, GDK_a, GDK_CONTROL_MASK,
-                          GTK_TEXT_MOVEMENT_PARAGRAPH_ENDS, -1);
+                          GTK_TEXT_MOVEMENT_LINE_ENDS, -1);
 
   add_move_insert_binding (binding_set, GDK_e, GDK_CONTROL_MASK,
-                          GTK_TEXT_MOVEMENT_PARAGRAPH_ENDS, 1);
+                          GTK_TEXT_MOVEMENT_LINE_ENDS, 1);
 
   add_move_insert_binding (binding_set, GDK_f, GDK_MOD1_MASK,
                           GTK_TEXT_MOVEMENT_WORD, 1);
@@ -493,12 +498,12 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
 
   gtk_binding_entry_add_signal (binding_set, GDK_k, GDK_CONTROL_MASK,
                                "delete_text", 2,
-                               GTK_TYPE_ENUM, GTK_TEXT_DELETE_HALF_PARAGRAPH,
+                               GTK_TYPE_ENUM, GTK_TEXT_DELETE_HALF_LINE,
                                GTK_TYPE_INT, 1);
 
   gtk_binding_entry_add_signal (binding_set, GDK_u, GDK_CONTROL_MASK,
                                "delete_text", 2,
-                               GTK_TYPE_ENUM, GTK_TEXT_DELETE_WHOLE_PARAGRAPH,
+                               GTK_TYPE_ENUM, GTK_TEXT_DELETE_WHOLE_LINE,
                                GTK_TYPE_INT, 1);
 
   gtk_binding_entry_add_signal (binding_set, GDK_space, GDK_MOD1_MASK,
@@ -614,6 +619,9 @@ gtk_text_view_init (GtkTextView *text_view)
   
   gtk_signal_connect (GTK_OBJECT (text_view->im_context), "commit",
                      GTK_SIGNAL_FUNC (gtk_text_view_commit_handler), text_view);
+
+  text_view->editable = TRUE;
+  text_view->cursor_visible = TRUE;
 }
 
 GtkWidget*
@@ -664,7 +672,7 @@ gtk_text_view_set_buffer (GtkTextView *text_view,
       if (text_view->layout)
         gtk_text_layout_set_buffer (text_view->layout, buffer);
 
-      gtk_text_buffer_get_iter_at_char (text_view->buffer, &start, 0);
+      gtk_text_buffer_get_iter_at_offset (text_view->buffer, &start, 0);
       
       text_view->dnd_mark = gtk_text_buffer_create_mark (text_view->buffer,
                                                         "__drag_target",
@@ -707,6 +715,16 @@ gtk_text_view_get_iter_at_pixel (GtkTextView *text_view,
                                      y + text_view->yoffset);
 }
 
+void
+gtk_text_view_get_iter_location (GtkTextView       *text_view,
+                                 const GtkTextIter *iter,
+                                 GdkRectangle      *location)
+{
+  g_return_if_fail (GTK_IS_TEXT_VIEW (text_view));
+  g_return_if_fail (gtk_text_iter_get_buffer (iter) == text_view->buffer);
+
+  gtk_text_layout_get_iter_location (text_view->layout, iter, location);
+}
 
 static void
 set_adjustment_clamped (GtkAdjustment *adj, gfloat val)
@@ -817,7 +835,7 @@ gtk_text_view_scroll_to_mark_adjusted (GtkTextView *text_view,
 
   if (scroll_inc != 0)
     {
-      set_adjustment_clamped (text_view->vadjustment,
+      set_adjustment_clamped (get_vadjustment (text_view),
                              current_y_scroll + scroll_inc);
       retval = TRUE;
     }
@@ -838,7 +856,7 @@ gtk_text_view_scroll_to_mark_adjusted (GtkTextView *text_view,
 
   if (scroll_inc != 0)
     {
-      set_adjustment_clamped (text_view->hadjustment,
+      set_adjustment_clamped (get_hadjustment (text_view),
                              current_x_scroll + scroll_inc);
       retval = TRUE;
     }
@@ -936,6 +954,62 @@ gtk_text_view_get_wrap_mode (GtkTextView *text_view)
   return text_view->wrap_mode;
 }
 
+void
+gtk_text_view_set_editable (GtkTextView *text_view,
+                            gboolean     setting)
+{
+  g_return_if_fail (GTK_IS_TEXT_VIEW (text_view));
+
+  if (text_view->editable != setting)
+    {
+      text_view->editable = setting;
+
+      if (text_view->layout)
+       {
+         text_view->layout->default_style->editable = text_view->editable;
+         gtk_text_layout_default_style_changed (text_view->layout);
+       }
+    }
+}
+
+gboolean
+gtk_text_view_get_editable (GtkTextView *text_view)
+{
+  g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), FALSE);
+  
+  return text_view->editable;
+}
+
+void
+gtk_text_view_set_cursor_visible    (GtkTextView   *text_view,
+                                     gboolean       setting)
+{
+  g_return_if_fail (GTK_IS_TEXT_VIEW (text_view));
+
+  if (text_view->cursor_visible != setting)
+    {
+      text_view->cursor_visible = setting;
+
+      if (GTK_WIDGET_HAS_FOCUS (text_view))
+        {
+          GtkTextMark *insert;
+  
+          insert = gtk_text_buffer_get_mark (text_view->buffer,
+                                             "insert");
+          gtk_text_mark_set_visible (insert, text_view->cursor_visible);
+        }
+    }
+}
+
+gboolean
+gtk_text_view_get_cursor_visible    (GtkTextView   *text_view)
+{
+  g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), FALSE);
+
+  return text_view->cursor_visible;
+}
+
+
 gboolean
 gtk_text_view_place_cursor_onscreen (GtkTextView *text_view)
 {
@@ -976,8 +1050,11 @@ gtk_text_view_finalize (GObject *object)
 
   text_view = GTK_TEXT_VIEW (object);  
 
-  gtk_object_unref (GTK_OBJECT (text_view->hadjustment));
-  gtk_object_unref (GTK_OBJECT (text_view->vadjustment));
+  if (text_view->hadjustment)
+    gtk_object_unref (GTK_OBJECT (text_view->hadjustment));
+  if (text_view->vadjustment)
+    gtk_object_unref (GTK_OBJECT (text_view->vadjustment));
+
   gtk_object_unref (GTK_OBJECT (text_view->im_context));
 
   (* G_OBJECT_CLASS (parent_class)->finalize) (object);
@@ -1060,8 +1137,9 @@ gtk_text_view_size_request (GtkWidget      *widget,
                            GtkRequisition *requisition)
 {
   /* Hrm */
-  requisition->width = 1;
-  requisition->height = 1;
+
+  requisition->width = 200;
+  requisition->height = 200;
 }
 
 static void
@@ -1101,6 +1179,10 @@ gtk_text_view_size_allocate (GtkWidget *widget,
   gtk_text_view_get_first_para_iter (text_view, &first_para);
   y = gtk_text_layout_get_line_y (text_view->layout, &first_para) + text_view->first_para_pixels;
 
+  /* Ensure h/v adj exist */
+  get_hadjustment (text_view);
+  get_vadjustment (text_view);
+  
   vadj = text_view->vadjustment;
   if (y > vadj->upper - vadj->page_size)
     y = MAX (0, vadj->upper - vadj->page_size);
@@ -1110,7 +1192,7 @@ gtk_text_view_size_allocate (GtkWidget *widget,
       vadj->value = text_view->yoffset = y;
       yoffset_changed = TRUE;
     }
-
+  
   text_view->hadjustment->page_size = allocation->width;
   text_view->hadjustment->page_increment = allocation->width / 2;
   text_view->hadjustment->lower = 0;
@@ -1233,15 +1315,14 @@ changed_handler (GtkTextLayout *layout,
       if (start_y + old_height <= text_view->yoffset - text_view->first_para_pixels)
        {
          text_view->yoffset += new_height - old_height;
-         text_view->vadjustment->value = text_view->yoffset;
+         get_vadjustment (text_view)->value = text_view->yoffset;
          yoffset_changed = TRUE;
        }
 
       gtk_text_view_scroll_calc_now (text_view);
 
       if (yoffset_changed)
-       gtk_adjustment_value_changed (text_view->vadjustment);
-       
+       gtk_adjustment_value_changed (get_vadjustment (text_view));
     }
 }
 
@@ -1412,6 +1493,39 @@ get_event_coordinates (GdkEvent *event, gint *x, gint *y)
   return FALSE;
 }
 
+static gint
+emit_event_on_tags (GtkWidget   *widget,
+                    GdkEvent    *event,
+                    GtkTextIter *iter)
+{
+  GSList *tags;
+  GSList *tmp;
+  gint retval = FALSE;
+  GtkTextView *text_view;
+
+  text_view = GTK_TEXT_VIEW (widget);
+  
+  tags = gtk_text_buffer_get_tags (text_view->buffer, iter);
+          
+  tmp = tags;
+  while (tmp != NULL)
+    {
+      GtkTextTag *tag = tmp->data;
+
+      if (gtk_text_tag_event (tag, GTK_OBJECT (widget), event, iter))
+        {
+          retval = TRUE;
+          break;
+        }
+
+      tmp = g_slist_next (tmp);
+    }
+
+  g_slist_free (tags);
+
+  return retval;
+}
+     
 static gint
 gtk_text_view_event (GtkWidget *widget, GdkEvent *event)
 {
@@ -1423,14 +1537,10 @@ gtk_text_view_event (GtkWidget *widget, GdkEvent *event)
   if (text_view->layout == NULL ||
       text_view->buffer == NULL)
     return FALSE;
-
-  /* FIXME eventually we really want to synthesize enter/leave
-     events here as the canvas does for canvas items */
   
   if (get_event_coordinates (event, &x, &y))
     {
       GtkTextIter iter;
-      gint retval = FALSE;
 
       x += text_view->xoffset;
       y += text_view->yoffset;
@@ -1442,33 +1552,23 @@ gtk_text_view_event (GtkWidget *widget, GdkEvent *event)
                                          &iter,
                                          x, y);
 
-        {
-          GSList *tags;
-          GSList *tmp;
-          
-          tags = gtk_text_buffer_get_tags (text_view->buffer, &iter);
-          
-          tmp = tags;
-          while (tmp != NULL)
-            {
-              GtkTextTag *tag = tmp->data;
+      return emit_event_on_tags (widget, event, &iter);
+    }
+  else if (event->type == GDK_KEY_PRESS ||
+           event->type == GDK_KEY_RELEASE)
+    {
+      GtkTextMark *insert;
+      GtkTextIter iter;
 
-              if (gtk_text_tag_event (tag, GTK_OBJECT (widget), event, &iter))
-                {
-                  retval = TRUE;
-                  break;
-                }
+      insert = gtk_text_buffer_get_mark (text_view->buffer,
+                                         "insert");      
 
-              tmp = g_slist_next (tmp);
-            }
+      gtk_text_buffer_get_iter_at_mark (text_view->buffer, &iter, insert);
 
-          g_slist_free (tags);
-        }
-        
-      return retval;
+      return emit_event_on_tags (widget, event, &iter);
     }
-
-  return FALSE;
+  else
+    return FALSE;
 }
 
 static gint
@@ -1490,7 +1590,8 @@ gtk_text_view_key_press_event (GtkWidget *widget, GdkEventKey *event)
     return TRUE;
   else if (event->keyval == GDK_Return)
     {
-      gtk_text_buffer_insert_at_cursor (text_view->buffer, "\n", 1);
+      gtk_text_buffer_insert_interactive_at_cursor (text_view->buffer, "\n", 1,
+                                                    text_view->editable);
       gtk_text_view_scroll_to_mark (text_view,
                                     gtk_text_buffer_get_mark (text_view->buffer,
                                                               "insert"),
@@ -1560,7 +1661,9 @@ gtk_text_view_button_press_event (GtkWidget *widget, GdkEventButton *event)
           
           gtk_text_buffer_paste_primary_selection (text_view->buffer,
                                                    &iter,
-                                                   event->time);
+                                                   event->time,
+                                                   TRUE,
+                                                   text_view->editable);
           return TRUE;
         }
       else if (event->button == 3)
@@ -1596,7 +1699,7 @@ gtk_text_view_focus_in_event (GtkWidget *widget, GdkEventFocus *event)
 
   insert = gtk_text_buffer_get_mark (GTK_TEXT_VIEW (widget)->buffer,
                                      "insert");
-  gtk_text_mark_set_visible (insert, TRUE);
+  gtk_text_mark_set_visible (insert, GTK_TEXT_VIEW (widget)->cursor_visible);
 
   gtk_text_view_start_cursor_blink (GTK_TEXT_VIEW (widget));
 
@@ -1762,7 +1865,7 @@ gtk_text_view_move_insert (GtkTextView *text_view,
                                                               "insert"));
   newplace = insert;
 
-  if (step == GTK_TEXT_MOVEMENT_LINE)
+  if (step == GTK_TEXT_MOVEMENT_WRAPPED_LINE)
     gtk_text_view_get_virtual_cursor_pos (text_view, &cursor_x_pos, NULL);
 
   switch (step)
@@ -1783,28 +1886,29 @@ gtk_text_view_move_insert (GtkTextView *text_view,
        gtk_text_iter_forward_word_ends (&newplace, count);
       break;
 
-    case GTK_TEXT_MOVEMENT_LINE:
+    case GTK_TEXT_MOVEMENT_WRAPPED_LINE:
       gtk_text_view_move_iter_by_lines (text_view, &newplace, count);
       gtk_text_layout_move_iter_to_x (text_view->layout, &newplace, cursor_x_pos);
       break;
       
-    case GTK_TEXT_MOVEMENT_PARAGRAPH:
+    case GTK_TEXT_MOVEMENT_LINE:
       /* This should almost certainly instead be doing the parallel thing to WORD */
-      gtk_text_iter_down_lines (&newplace, count);
+      /*       gtk_text_iter_down_lines (&newplace, count); */
+      /* FIXME */
       break;
       
-    case GTK_TEXT_MOVEMENT_PARAGRAPH_ENDS:
+    case GTK_TEXT_MOVEMENT_LINE_ENDS:
       if (count > 0)
        gtk_text_iter_forward_to_newline (&newplace);
       else if (count < 0)
-       gtk_text_iter_set_line_char (&newplace, 0);
+       gtk_text_iter_set_line_offset (&newplace, 0);
       break;
       
     case GTK_TEXT_MOVEMENT_BUFFER_ENDS:
       if (count > 0)
        gtk_text_buffer_get_last_iter (text_view->buffer, &newplace);
       else if (count < 0)
-       gtk_text_buffer_get_iter_at_char (text_view->buffer, &newplace, 0);
+       gtk_text_buffer_get_iter_at_offset (text_view->buffer, &newplace, 0);
       break;
       
     default:
@@ -1825,7 +1929,7 @@ gtk_text_view_move_insert (GtkTextView *text_view,
                                     gtk_text_buffer_get_mark (text_view->buffer,
                                                               "insert"), 0);
 
-      if (step == GTK_TEXT_MOVEMENT_LINE)
+      if (step == GTK_TEXT_MOVEMENT_WRAPPED_LINE)
        {
          gtk_text_view_set_virtual_cursor_pos (text_view, cursor_x_pos, -1);
        }
@@ -1865,7 +1969,7 @@ gtk_text_view_scroll_text (GtkTextView *text_view,
     {
     default:
     case GTK_TEXT_SCROLL_TO_TOP:
-      gtk_text_buffer_get_iter_at_char (text_view->buffer, &anchor, 0);
+      gtk_text_buffer_get_iter_at_offset (text_view->buffer, &anchor, 0);
       y0 = 0;
       y1 = adj->page_size;
       break;
@@ -1954,7 +2058,7 @@ find_whitepace_region (const GtkTextIter *center,
   *end = *center;
 
   if (gtk_text_iter_backward_find_char (start, not_whitespace, NULL))
-    gtk_text_iter_forward_char (start); /* we want the first whitespace... */
+    gtk_text_iter_next_char (start); /* we want the first whitespace... */
   if (whitespace (gtk_text_iter_get_char (end), NULL))
     gtk_text_iter_forward_find_char (end, not_whitespace, NULL);
   
@@ -1974,7 +2078,8 @@ gtk_text_view_delete_text (GtkTextView *text_view,
   if (type == GTK_TEXT_DELETE_CHAR)
     {
       /* Char delete deletes the selection, if one exists */
-      if (gtk_text_buffer_delete_selection (text_view->buffer))
+      if (gtk_text_buffer_delete_selection (text_view->buffer, TRUE,
+                                            text_view->editable))
         return;
     }
   
@@ -2002,13 +2107,13 @@ gtk_text_view_delete_text (GtkTextView *text_view,
     case GTK_TEXT_DELETE_WHOLE_WORD:
       break;
       
-    case GTK_TEXT_DELETE_HALF_LINE:
+    case GTK_TEXT_DELETE_HALF_WRAPPED_LINE:
       break;
 
-    case GTK_TEXT_DELETE_WHOLE_LINE:
+    case GTK_TEXT_DELETE_WHOLE_WRAPPED_LINE:
       break;
 
-    case GTK_TEXT_DELETE_HALF_PARAGRAPH:
+    case GTK_TEXT_DELETE_HALF_LINE:
       while (count > 0)
         {
           if (!gtk_text_iter_forward_to_newline (&end))
@@ -2021,10 +2126,10 @@ gtk_text_view_delete_text (GtkTextView *text_view,
          and support that */
       break;
       
-    case GTK_TEXT_DELETE_WHOLE_PARAGRAPH:
+    case GTK_TEXT_DELETE_WHOLE_LINE:
       if (count > 0)
         {
-          gtk_text_iter_set_line_char (&start, 0);
+          gtk_text_iter_set_line_offset (&start, 0);
           gtk_text_iter_forward_to_newline (&end);
 
           /* Do the lines beyond the first. */
@@ -2054,10 +2159,14 @@ gtk_text_view_delete_text (GtkTextView *text_view,
 
   if (!gtk_text_iter_equal (&start, &end))
     {
-      gtk_text_buffer_delete (text_view->buffer, &start, &end);
-      
-      if (leave_one)
-        gtk_text_buffer_insert_at_cursor (text_view->buffer, " ", 1);
+      if (gtk_text_buffer_delete_interactive (text_view->buffer, &start, &end,
+                                              text_view->editable))
+        {
+          if (leave_one)
+            gtk_text_buffer_insert_interactive_at_cursor (text_view->buffer,
+                                                          " ", 1,
+                                                          text_view->editable);
+        }
       
       gtk_text_view_scroll_to_mark (text_view,
                                     gtk_text_buffer_get_mark (text_view->buffer, "insert"),
@@ -2068,7 +2177,7 @@ gtk_text_view_delete_text (GtkTextView *text_view,
 static void
 gtk_text_view_cut_text (GtkTextView *text_view)
 {
-  gtk_text_buffer_cut (text_view->buffer, GDK_CURRENT_TIME);
+  gtk_text_buffer_cut (text_view->buffer, GDK_CURRENT_TIME, TRUE, text_view->editable);
   gtk_text_view_scroll_to_mark (text_view,
                                 gtk_text_buffer_get_mark (text_view->buffer,
                                                           "insert"),
@@ -2088,7 +2197,7 @@ gtk_text_view_copy_text (GtkTextView *text_view)
 static void
 gtk_text_view_paste_text (GtkTextView *text_view)
 {
-  gtk_text_buffer_paste_clipboard (text_view->buffer, GDK_CURRENT_TIME);
+  gtk_text_buffer_paste_clipboard (text_view->buffer, GDK_CURRENT_TIME, TRUE, text_view->editable);
   gtk_text_view_scroll_to_mark (text_view,
                                 gtk_text_buffer_get_mark (text_view->buffer,
                                                           "insert"),
@@ -2338,11 +2447,13 @@ gtk_text_view_scroll_calc_now (GtkTextView *text_view)
       text_view->width = width;
       text_view->height = height;
       
-      gtk_text_view_set_adjustment_upper (text_view->hadjustment,
+      gtk_text_view_set_adjustment_upper (get_hadjustment (text_view),
                                          MAX (widget->allocation.width, width));
-      gtk_text_view_set_adjustment_upper (text_view->vadjustment
+      gtk_text_view_set_adjustment_upper (get_vadjustment (text_view)
                                          MAX (widget->allocation.height, height));
 
+      /* hadj/vadj exist since we called get_hadjustment/get_vadjustment above */
+      
       /* Set up the step sizes; we'll say that a page is
          our allocation minus one step, and a step is
          1/10 of our allocation. */
@@ -2567,9 +2678,10 @@ gtk_text_view_drag_data_get (GtkWidget        *widget,
 
 static void
 gtk_text_view_drag_data_delete (GtkWidget        *widget,
-                            GdkDragContext   *context)
+                                GdkDragContext   *context)
 {
-  gtk_text_buffer_delete_selection (GTK_TEXT_VIEW (widget)->buffer);
+  gtk_text_buffer_delete_selection (GTK_TEXT_VIEW (widget)->buffer,
+                                    TRUE, GTK_TEXT_VIEW (widget)->editable);
 }
 
 static void
@@ -2610,9 +2722,18 @@ gtk_text_view_drag_motion (GtkWidget        *widget,
     }
   else
     {
-      gtk_text_mark_set_visible (text_view->dnd_mark, TRUE);
-      
-      gdk_drag_status (context, context->suggested_action, time);
+      if (gtk_text_iter_editable (&newplace, text_view->editable))
+        {
+          gtk_text_mark_set_visible (text_view->dnd_mark, text_view->cursor_visible);
+          
+          gdk_drag_status (context, context->suggested_action, time);
+        }
+      else
+        {
+          /* Can't drop here. */
+          gdk_drag_status (context, 0, time);
+          gtk_text_mark_set_visible (text_view->dnd_mark, FALSE);
+        }
     }
 
   gtk_text_buffer_move_mark (text_view->buffer,
@@ -2712,16 +2833,18 @@ gtk_text_view_drag_data_received (GtkWidget        *widget,
 
         utf = gtk_text_latin1_to_utf ((const gchar*)selection_data->data,
                                       selection_data->length);
-        gtk_text_buffer_insert (text_view->buffer, &drop_point,
-                                 utf, -1);
+        gtk_text_buffer_insert_interactive (text_view->buffer, &drop_point,
+                                            utf, -1,
+                                            text_view->editable);
         g_free (utf);
       }
       break;
       
     case UTF8:
-      gtk_text_buffer_insert (text_view->buffer, &drop_point,
-                               (const gchar *)selection_data->data,
-                               selection_data->length);
+      gtk_text_buffer_insert_interactive (text_view->buffer, &drop_point,
+                                          (const gchar *)selection_data->data,
+                                          selection_data->length,
+                                          text_view->editable);
       break;
       
     case CTEXT:
@@ -2737,15 +2860,26 @@ gtk_text_view_drag_data_received (GtkWidget        *widget,
                                                &list);
        for (i=0; i<count; i++)
           {
-            /* FIXME this is broken, it assumes the CTEXT is latin1
-               when it probably isn't. */
-            gchar *utf;
-
-            utf = gtk_text_latin1_to_utf (list[i], strlen (list[i]));
+            /* list contains stuff in our default encoding */
+            gboolean free_utf = FALSE;
+            gchar *utf = NULL;
+            gchar *charset = NULL;
             
-            gtk_text_buffer_insert (text_view->buffer, &drop_point, utf, -1);
-
-            g_free (utf);
+            if (g_get_charset (&charset))
+              {
+                utf = g_convert (list[i], -1,
+                                 "UTF8", charset, NULL);
+                free_utf = TRUE;
+              }
+            else
+              utf = list[i];
+
+            gtk_text_buffer_insert_interactive (text_view->buffer,
+                                                &drop_point, utf, -1,
+                                                text_view->editable);
+
+            if (free_utf)
+              g_free(utf);
           }
 
        if (count > 0)
@@ -2758,6 +2892,33 @@ gtk_text_view_drag_data_received (GtkWidget        *widget,
     }
 }
 
+static GtkAdjustment*
+get_hadjustment (GtkTextView *text_view)
+{
+  if (text_view->hadjustment == NULL)
+    gtk_text_view_set_scroll_adjustments (text_view,
+                                          (GtkAdjustment*)
+                                          gtk_adjustment_new (0.0, 0.0, 0.0,
+                                                              0.0, 0.0, 0.0),
+                                          text_view->vadjustment);
+
+  return text_view->hadjustment;
+}
+
+static GtkAdjustment*
+get_vadjustment (GtkTextView *text_view)
+{
+  if (text_view->vadjustment == NULL)
+    gtk_text_view_set_scroll_adjustments (text_view,
+                                          text_view->hadjustment,
+                                          (GtkAdjustment*)
+                                          gtk_adjustment_new (0.0, 0.0, 0.0,
+                                                              0.0, 0.0, 0.0));
+
+  return text_view->vadjustment;
+}
+
+
 static void
 gtk_text_view_set_scroll_adjustments (GtkTextView   *text_view,
                                      GtkAdjustment *hadj,
@@ -2858,17 +3019,20 @@ gtk_text_view_commit_handler (GtkIMContext  *context,
                              const gchar   *str,
                              GtkTextView   *text_view)
 {
-  gtk_text_buffer_delete_selection (text_view->buffer);
+  gtk_text_buffer_delete_selection (text_view->buffer, TRUE,
+                                    text_view->editable);
 
   if (!strcmp (str, "\n"))
     {
-      gtk_text_buffer_insert_at_cursor (text_view->buffer, "\n", 1);
+      gtk_text_buffer_insert_interactive_at_cursor (text_view->buffer, "\n", 1,
+                                                    text_view->editable);
     }
   else
     {
       if (text_view->overwrite_mode)
        gtk_text_view_delete_text (text_view, GTK_TEXT_DELETE_CHAR, 1);
-      gtk_text_buffer_insert_at_cursor (text_view->buffer, str, strlen (str));
+      gtk_text_buffer_insert_interactive_at_cursor (text_view->buffer, str, -1,
+                                                    text_view->editable);
     }
   
   gtk_text_view_scroll_to_mark (text_view,
index 8af1a9e7f12308feef4d310f55378da02ccd69ed..d1dca9ebf0cd0128fbf1dc994159b7ecf6a0aaf8 100644 (file)
@@ -13,9 +13,9 @@ typedef enum {
   GTK_TEXT_MOVEMENT_CHAR,       /* move by forw/back chars */
   GTK_TEXT_MOVEMENT_POSITIONS,  /* move by left/right chars */
   GTK_TEXT_MOVEMENT_WORD,       /* move by forward/back words */
-  GTK_TEXT_MOVEMENT_LINE,       /* move up/down lines (wrapped lines) */
-  GTK_TEXT_MOVEMENT_PARAGRAPH,  /* move up/down paragraphs (newline-ended lines) */
-  GTK_TEXT_MOVEMENT_PARAGRAPH_ENDS,   /* move to either end of a paragraph */
+  GTK_TEXT_MOVEMENT_WRAPPED_LINE,       /* move up/down lines (wrapped lines) */
+  GTK_TEXT_MOVEMENT_LINE,  /* move up/down paragraphs (newline-ended lines) */
+  GTK_TEXT_MOVEMENT_LINE_ENDS,   /* move to either end of a paragraph */
   GTK_TEXT_MOVEMENT_BUFFER_ENDS       /* move to ends of the buffer */
 } GtkTextViewMovementStep;
 
@@ -32,10 +32,10 @@ typedef enum {
                                  left/right of cursor if we're in the middle
                                  of a word */
   GTK_TEXT_DELETE_WHOLE_WORD,
-  GTK_TEXT_DELETE_HALF_LINE,
-  GTK_TEXT_DELETE_WHOLE_LINE,
-  GTK_TEXT_DELETE_HALF_PARAGRAPH,  /* like C-k in Emacs (or its reverse) */
-  GTK_TEXT_DELETE_WHOLE_PARAGRAPH, /* C-k in pico, kill whole line */
+  GTK_TEXT_DELETE_HALF_WRAPPED_LINE,
+  GTK_TEXT_DELETE_WHOLE_WRAPPED_LINE,
+  GTK_TEXT_DELETE_HALF_LINE,  /* like C-k in Emacs (or its reverse) */
+  GTK_TEXT_DELETE_WHOLE_LINE, /* C-k in pico, kill whole line */
   GTK_TEXT_DELETE_WHITESPACE,      /* M-\ in Emacs */
   GTK_TEXT_DELETE_WHITESPACE_LEAVE_ONE /* M-space in Emacs */
 } GtkTextViewDeleteType;
@@ -64,6 +64,10 @@ struct _GtkTextView {
 
   GtkWrapMode wrap_mode;       /* Default wrap mode */
 
+  gboolean editable;            /* default editability */
+
+  gboolean cursor_visible;
+  
   GdkWindow *bin_window;
   GtkAdjustment *hadjustment;
   GtkAdjustment *vadjustment;
@@ -144,6 +148,18 @@ void           gtk_text_view_set_wrap_mode         (GtkTextView   *text_view,
                                                    GtkWrapMode    wrap_mode);
 GtkWrapMode    gtk_text_view_get_wrap_mode         (GtkTextView   *text_view);
 
+void           gtk_text_view_set_editable          (GtkTextView   *text_view,
+                                                    gboolean       setting);
+gboolean       gtk_text_view_get_editable          (GtkTextView   *text_view);
+
+void           gtk_text_view_set_cursor_visible    (GtkTextView   *text_view,
+                                                    gboolean       setting);
+gboolean       gtk_text_view_get_cursor_visible    (GtkTextView   *text_view);
+
+void           gtk_text_view_get_iter_location     (GtkTextView   *text_view,
+                                                    const GtkTextIter *iter,
+                                                    GdkRectangle  *location);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index fad48f0399bb171477f6f071e04a014b38878be9..bbff4d00aeddde7bf1816d8facde2807ee78bb31 100644 (file)
@@ -20,6 +20,8 @@ struct _Buffer
   GtkTextBuffer *buffer;
   char *filename;
   gint untitled_serial;
+  GtkTextTag *not_editable_tag;
+  GtkTextTag *found_text_tag;
 };
 
 struct _View
@@ -41,6 +43,9 @@ static gboolean save_buffer        (Buffer *buffer);
 static gboolean save_as_buffer     (Buffer *buffer);
 static char *   buffer_pretty_name (Buffer *buffer);
 static void     buffer_filename_set (Buffer *buffer);
+static void     buffer_search_forward (Buffer *buffer,
+                                       const char *str,
+                                       View *view);
 
 static View *view_from_widget (GtkWidget *widget);
 
@@ -290,14 +295,14 @@ msgbox_run (GtkWindow  *parent,
  * Example buffer filling code
  */
 static gint
-blink_timeout(gpointer data)
+blink_timeout (gpointer data)
 {
   GtkTextTag *tag;
   static gboolean flip = FALSE;
   
-  tag = GTK_TEXT_TAG(data);
+  tag = GTK_TEXT_TAG (data);
 
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                  "foreground", flip ? "blue" : "purple",
                  NULL);
 
@@ -307,42 +312,46 @@ blink_timeout(gpointer data)
 }
 
 static gint
-tag_event_handler(GtkTextTag *tag, GtkWidget *widget, GdkEvent *event,
+tag_event_handler (GtkTextTag *tag, GtkWidget *widget, GdkEvent *event,
                   const GtkTextIter *iter, gpointer user_data)
 {
   gint char_index;
 
-  char_index = gtk_text_iter_get_char_index(iter);
+  char_index = gtk_text_iter_get_offset (iter);
   
   switch (event->type)
     {
     case GDK_MOTION_NOTIFY:
-      printf("Motion event at char %d tag `%s'\n",
+      printf ("Motion event at char %d tag `%s'\n",
              char_index, tag->name);
       break;
         
     case GDK_BUTTON_PRESS:
-      printf("Button press at char %d tag `%s'\n",
+      printf ("Button press at char %d tag `%s'\n",
              char_index, tag->name);
       break;
         
     case GDK_2BUTTON_PRESS:
-      printf("Double click at char %d tag `%s'\n",
+      printf ("Double click at char %d tag `%s'\n",
              char_index, tag->name);
       break;
         
     case GDK_3BUTTON_PRESS:
-      printf("Triple click at char %d tag `%s'\n",
+      printf ("Triple click at char %d tag `%s'\n",
              char_index, tag->name);
       break;
         
     case GDK_BUTTON_RELEASE:
-      printf("Button release at char %d tag `%s'\n",
+      printf ("Button release at char %d tag `%s'\n",
              char_index, tag->name);
       break;
         
     case GDK_KEY_PRESS:
     case GDK_KEY_RELEASE:
+      printf ("Key event at char %d tag `%s'\n",
+              char_index, tag->name);
+      break;
+      
     case GDK_ENTER_NOTIFY:
     case GDK_LEAVE_NOTIFY:
     case GDK_PROPERTY_NOTIFY:
@@ -365,12 +374,12 @@ tag_event_handler(GtkTextTag *tag, GtkWidget *widget, GdkEvent *event,
 }
 
 static void
-setup_tag(GtkTextTag *tag)
+setup_tag (GtkTextTag *tag)
 {
 
-  gtk_signal_connect(GTK_OBJECT(tag),
+  gtk_signal_connect (GTK_OBJECT (tag),
                      "event",
-                     GTK_SIGNAL_FUNC(tag_event_handler),
+                     GTK_SIGNAL_FUNC (tag_event_handler),
                      NULL);
 }
 
@@ -413,77 +422,77 @@ fill_example_buffer (GtkTextBuffer *buffer)
   int i;
   char *str;
   
-  tag = gtk_text_buffer_create_tag(buffer, "fg_blue");
+  tag = gtk_text_buffer_create_tag (buffer, "fg_blue");
 
-  /*       gtk_timeout_add(1000, blink_timeout, tag); */
+  /*       gtk_timeout_add (1000, blink_timeout, tag); */
       
-  setup_tag(tag);
+  setup_tag (tag);
   
   color.red = color.green = 0;
   color.blue = 0xffff;
   color2.red = 0xfff;
   color2.blue = 0x0;
   color2.green = 0;
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                 "foreground_gdk", &color,
                 "background_gdk", &color2,
                 "font", "Sans 24",
                 NULL);
 
-  tag = gtk_text_buffer_create_tag(buffer, "fg_red");
+  tag = gtk_text_buffer_create_tag (buffer, "fg_red");
 
-  setup_tag(tag);
+  setup_tag (tag);
       
   color.blue = color.green = 0;
   color.red = 0xffff;
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                 "offset", -4,
                 "foreground_gdk", &color,
                 NULL);
 
-  tag = gtk_text_buffer_create_tag(buffer, "bg_green");
+  tag = gtk_text_buffer_create_tag (buffer, "bg_green");
 
-  setup_tag(tag);
+  setup_tag (tag);
       
   color.blue = color.red = 0;
   color.green = 0xffff;
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                 "background_gdk", &color,
                 "font", "Sans 10",
                 NULL);
 
-  tag = gtk_text_buffer_create_tag(buffer, "overstrike");
+  tag = gtk_text_buffer_create_tag (buffer, "overstrike");
 
-  setup_tag(tag);
+  setup_tag (tag);
       
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                 "overstrike", TRUE,
                 NULL);
 
 
-  tag = gtk_text_buffer_create_tag(buffer, "underline");
+  tag = gtk_text_buffer_create_tag (buffer, "underline");
 
-  setup_tag(tag);
+  setup_tag (tag);
       
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                 "underline", PANGO_UNDERLINE_SINGLE,
                 NULL);
 
-  setup_tag(tag);
+  setup_tag (tag);
       
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                 "underline", PANGO_UNDERLINE_SINGLE,
                 NULL);
 
-  tag = gtk_text_buffer_create_tag(buffer, "centered");
+  tag = gtk_text_buffer_create_tag (buffer, "centered");
       
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                 "justify", GTK_JUSTIFY_CENTER,
                 NULL);
 
-  tag = gtk_text_buffer_create_tag(buffer, "rtl_quote");
+  tag = gtk_text_buffer_create_tag (buffer, "rtl_quote");
       
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                 "wrap_mode", GTK_WRAPMODE_WORD,
                 "direction", GTK_TEXT_DIR_RTL,
                 "left_wrapped_line_margin", 20,
@@ -492,31 +501,31 @@ fill_example_buffer (GtkTextBuffer *buffer)
                 NULL);
   
   pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL,
-                                                 gtk_widget_get_default_colormap(),
+                                                 gtk_widget_get_default_colormap (),
                                                  &mask,
                                                  NULL, book_closed_xpm);
   
-  g_assert(pixmap != NULL);
+  g_assert (pixmap != NULL);
   
   i = 0;
   while (i < 100)
     {
       GtkTextMark * temp_mark;
       
-      gtk_text_buffer_get_iter_at_char(buffer, &iter, 0);
+      gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
           
       gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
           
-      str = g_strdup_printf("%d Hello World! blah blah blah blah blah blah blah blah blah blah blah blah\nwoo woo woo woo woo woo woo woo woo woo woo woo woo woo woo\n",
+      str = g_strdup_printf ("%d Hello World! blah blah blah blah blah blah blah blah blah blah blah blah\nwoo woo woo woo woo woo woo woo woo woo woo woo woo woo woo\n",
                            i);
       
-      gtk_text_buffer_insert(buffer, &iter, str, -1);
+      gtk_text_buffer_insert (buffer, &iter, str, -1);
 
-      g_free(str);
+      g_free (str);
       
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter, 0, 5);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 0, 5);
           
-      gtk_text_buffer_insert(buffer, &iter,
+      gtk_text_buffer_insert (buffer, &iter,
                             "(Hello World!)\nfoo foo Hello this is some text we are using to text word wrap. It has punctuation! gee; blah - hmm, great.\nnew line with a significant quantity of text on it. This line really does contain some text. More text! More text! More text!\n"
                             /* This is UTF8 stuff, Emacs doesn't
                                really know how to display it */
@@ -526,59 +535,59 @@ fill_example_buffer (GtkTextBuffer *buffer)
         gtk_text_buffer_create_mark (buffer, "tmp_mark", &iter, TRUE);
 
 #if 1
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter, 0, 6);
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter2, 0, 13);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 0, 6);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter2, 0, 13);
 
-      gtk_text_buffer_apply_tag(buffer, "fg_blue", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
 
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter, 1, 10);
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter2, 1, 16);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 1, 10);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter2, 1, 16);
 
-      gtk_text_buffer_apply_tag(buffer, "underline", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "underline", &iter, &iter2);
 
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter, 1, 14);
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter2, 1, 24);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 1, 14);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter2, 1, 24);
 
-      gtk_text_buffer_apply_tag(buffer, "overstrike", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "overstrike", &iter, &iter2);
           
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter, 0, 9);
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter2, 0, 16);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 0, 9);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter2, 0, 16);
 
-      gtk_text_buffer_apply_tag(buffer, "bg_green", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "bg_green", &iter, &iter2);
   
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter, 4, 2);
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter2, 4, 10);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 4, 2);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter2, 4, 10);
 
-      gtk_text_buffer_apply_tag(buffer, "bg_green", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "bg_green", &iter, &iter2);
 
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter, 4, 8);
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter2, 4, 15);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 4, 8);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter2, 4, 15);
 
-      gtk_text_buffer_apply_tag(buffer, "fg_red", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
 #endif
 
       gtk_text_buffer_get_iter_at_mark (buffer, &iter, temp_mark);
       gtk_text_buffer_insert (buffer, &iter, "Centered text!\n", -1);
          
       gtk_text_buffer_get_iter_at_mark (buffer, &iter2, temp_mark);
-      gtk_text_buffer_apply_tag (buffer, "centered", &iter2, &iter);
+      gtk_text_buffer_apply_tag_by_name (buffer, "centered", &iter2, &iter);
 
       gtk_text_buffer_move_mark (buffer, temp_mark, &iter);
       gtk_text_buffer_insert (buffer, &iter, "Word wrapped, Right-to-left Quote\n", -1);
       gtk_text_buffer_insert (buffer, &iter, "وقد بدأ ثلاث من أكثر المؤسسات تقدما في شبكة اكسيون برامجها كمنظمات لا تسعى للربح، ثم تحولت في السنوات الخمس الماضية إلى مؤسسات مالية منظمة، وباتت جزءا من النظام المالي في بلدانها، ولكنها تتخصص في خدمة قطاع المشروعات الصغيرة. وأحد أكثر هذه المؤسسات نجاحا هو »بانكوسول« في بوليفيا.\n", -1);
       gtk_text_buffer_get_iter_at_mark (buffer, &iter2, temp_mark);
-      gtk_text_buffer_apply_tag (buffer, "rtl_quote", &iter2, &iter);
+      gtk_text_buffer_apply_tag_by_name (buffer, "rtl_quote", &iter2, &iter);
          
       ++i;
     }
 
-  gdk_pixmap_unref(pixmap);
+  gdk_pixmap_unref (pixmap);
   if (mask)
-    gdk_bitmap_unref(mask);
+    gdk_bitmap_unref (mask);
   
-  printf("%d lines %d chars\n",
-        gtk_text_buffer_get_line_count(buffer),
-        gtk_text_buffer_get_char_count(buffer));
+  printf ("%d lines %d chars\n",
+        gtk_text_buffer_get_line_count (buffer),
+        gtk_text_buffer_get_char_count (buffer));
 
   gtk_text_buffer_set_modified (buffer, FALSE);
 }
@@ -591,7 +600,7 @@ fill_file_buffer (GtkTextBuffer *buffer, const char *filename)
   gint remaining = 0;
   GtkTextIter iter, end;
 
-  f = fopen(filename, "r");
+  f = fopen (filename, "r");
   
   if (f == NULL)
     {
@@ -602,7 +611,7 @@ fill_file_buffer (GtkTextBuffer *buffer, const char *filename)
       return FALSE;
     }
   
-  gtk_text_buffer_get_iter_at_char(buffer, &iter, 0);
+  gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
   while (!feof (f))
     {
       gint count;
@@ -650,7 +659,7 @@ fill_file_buffer (GtkTextBuffer *buffer, const char *filename)
 }
 
 static gint
-delete_event_cb(GtkWidget *window, GdkEventAny *event, gpointer data)
+delete_event_cb (GtkWidget *window, GdkEventAny *event, gpointer data)
 {
   View *view = view_from_widget (window);
 
@@ -801,7 +810,7 @@ do_exit    (gpointer             callback_data,
       tmp_list = tmp_list->next;
     }
 
-  gtk_main_quit();
+  gtk_main_quit ();
   pop_active_window ();
 }
 
@@ -839,6 +848,118 @@ do_direction_changed (gpointer             callback_data,
   gtk_widget_queue_resize (view->text_view);
 }
 
+static void
+do_editable_changed (gpointer callback_data,
+                     guint callback_action,
+                     GtkWidget *widget)
+{
+  View *view = view_from_widget (widget);
+
+  gtk_text_view_set_editable (GTK_TEXT_VIEW (view->text_view), callback_action);
+}
+
+static void
+do_cursor_visible_changed (gpointer callback_data,
+                           guint callback_action,
+                           GtkWidget *widget)
+{
+  View *view = view_from_widget (widget);
+
+  gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view->text_view), callback_action);
+}
+
+static void
+do_apply_editable (gpointer callback_data,
+                   guint callback_action,
+                   GtkWidget *widget)
+{
+  View *view = view_from_widget (widget);
+  GtkTextIter start;
+  GtkTextIter end;
+  
+  if (gtk_text_buffer_get_selection_bounds (view->buffer->buffer,
+                                            &start, &end))
+    {
+      if (callback_action)
+        {
+          gtk_text_buffer_remove_tag (view->buffer->buffer,
+                                      view->buffer->not_editable_tag,
+                                      &start, &end);
+        }
+      else
+        {
+          gtk_text_buffer_apply_tag (view->buffer->buffer,
+                                     view->buffer->not_editable_tag,
+                                     &start, &end);
+        }
+    }
+}
+
+static void
+dialog_response_callback (GtkWidget *dialog, gint response_id, gpointer data)
+{
+  GtkTextBuffer *buffer;
+  View *view = data;
+  GtkTextIter start, end;
+  gchar *search_string;
+  
+  buffer = gtk_object_get_data (GTK_OBJECT (dialog), "buffer");
+
+  gtk_text_buffer_get_bounds (buffer, &start, &end);
+
+  /* Remove trailing newline */
+  gtk_text_iter_prev_char (&end);
+  
+  search_string = gtk_text_iter_get_text (&start, &end);
+
+  printf ("Searching for `%s'\n", search_string);
+  
+  buffer_search_forward (view->buffer, search_string, view);
+
+  g_free (search_string);
+  
+  gtk_widget_destroy (dialog);
+}
+
+static void
+do_search (gpointer callback_data,
+           guint callback_action,
+           GtkWidget *widget)
+{
+  View *view = view_from_widget (widget);
+  GtkWidget *dialog;
+  GtkWidget *search_text;
+  GtkTextBuffer *buffer;
+  
+  dialog = gtk_dialog_new_with_buttons ("Search",
+                                        GTK_WINDOW (view->window),
+                                        GTK_DIALOG_DESTROY_WITH_PARENT,
+                                        GTK_STOCK_BUTTON_CLOSE,
+                                        GTK_RESPONSE_NONE, NULL);
+
+  buffer = gtk_text_buffer_new (NULL);
+
+  /* FIXME memory leak once buffer is a GObject */
+  search_text = gtk_text_view_new_with_buffer (buffer);
+
+  gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->vbox),
+                    search_text,
+                    TRUE, TRUE, 0);
+
+  gtk_object_set_data (GTK_OBJECT (dialog), "buffer", buffer);
+  
+  gtk_signal_connect (GTK_OBJECT (dialog),
+                      "response",
+                      GTK_SIGNAL_FUNC (dialog_response_callback),
+                      view);
+
+  gtk_widget_show (search_text);
+
+  gtk_widget_grab_focus (search_text);
+  
+  gtk_widget_show_all (dialog);
+}
+
 static void
 view_init_menus (View *view)
 {
@@ -889,13 +1010,26 @@ static GtkItemFactoryEntry menu_items[] =
   { "/File/_Close",     "<control>W" , do_close,    0, NULL },
   { "/File/E_xit",      "<control>Q" , do_exit,     0, NULL },
 
+  { "/_Edit", NULL, 0, 0, "<Branch>" },
+  { "/Edit/Find...", NULL, do_search, 0, NULL },
+
   { "/_Settings",        NULL,         0,                0, "<Branch>" },
   { "/Settings/Wrap _Off",   NULL,      do_wrap_changed,  GTK_WRAPMODE_NONE, "<RadioItem>" },
   { "/Settings/Wrap _Words", NULL,      do_wrap_changed,  GTK_WRAPMODE_WORD, "/Settings/Wrap Off" },
   { "/Settings/sep1",        NULL,      0,                0, "<Separator>" },
+  { "/Settings/Editable", NULL,      do_editable_changed,  TRUE, "<RadioItem>" },
+  { "/Settings/Not editable",    NULL,      do_editable_changed,  FALSE, "/Settings/Editable" },
+  { "/Settings/sep1",        NULL,      0,                0, "<Separator>" },
+
+  { "/Settings/Cursor visible",    NULL,      do_cursor_visible_changed,  TRUE, "<RadioItem>" },
+  { "/Settings/Cursor not visible", NULL,      do_cursor_visible_changed,  FALSE, "/Settings/Cursor visible" },
+  { "/Settings/sep1",        NULL,      0,                0, "<Separator>" },
+  
   { "/Settings/Left-to-Right", NULL,    do_direction_changed,  GTK_TEXT_DIR_LTR, "<RadioItem>" },
   { "/Settings/Right-to-Left", NULL,    do_direction_changed,  GTK_TEXT_DIR_RTL, "/Settings/Left-to-Right" },
-  
+  { "/_Attributes",      NULL,         0,                0, "<Branch>" },
+  { "/Attributes/Editable",      NULL,         do_apply_editable, TRUE, NULL },
+  { "/Attributes/Not editable",          NULL,         do_apply_editable, FALSE, NULL },
   { "/_Test",           NULL,         0,           0, "<Branch>" },
   { "/Test/_Example",           NULL,         do_example,  0, NULL },
 };
@@ -938,7 +1072,7 @@ save_buffer (Buffer *buffer)
     }
   else
     {
-      gtk_text_buffer_get_iter_at_char (buffer->buffer, &start, 0);
+      gtk_text_buffer_get_iter_at_offset (buffer->buffer, &start, 0);
       gtk_text_buffer_get_last_iter (buffer->buffer, &end);
   
       chars = gtk_text_buffer_get_slice (buffer->buffer, &start, &end, FALSE);
@@ -988,7 +1122,7 @@ save_as_ok_func (const char *filename, gpointer data)
     {
       struct stat statbuf;
 
-      if (stat(filename, &statbuf) == 0)
+      if (stat (filename, &statbuf) == 0)
        {
          gchar *err = g_strdup_printf ("Ovewrite existing file '%s'?", filename);
          gint result = msgbox_run (NULL, err, "Yes", "No", NULL, 1);
@@ -1061,6 +1195,15 @@ create_buffer (void)
   buffer->filename = NULL;
   buffer->untitled_serial = -1;
 
+  buffer->not_editable_tag = gtk_text_buffer_create_tag (buffer->buffer, NULL);
+  gtk_object_set (GTK_OBJECT (buffer->not_editable_tag),
+                  "editable", FALSE,
+                  "foreground", "purple", NULL);
+
+  buffer->found_text_tag = gtk_text_buffer_create_tag (buffer->buffer, NULL);
+  gtk_object_set (GTK_OBJECT (buffer->found_text_tag),
+                  "foreground", "red", NULL);
+  
   buffers = g_slist_prepend (buffers, buffer);
   
   return buffer;
@@ -1107,6 +1250,60 @@ buffer_filename_set (Buffer *buffer)
     }
 }
 
+static void
+buffer_search_forward (Buffer *buffer, const char *str,
+                       View *view)
+{
+  GtkTextIter iter;
+  GtkTextIter start, end;
+  gint char_len;
+  int i = 0;
+  GtkWidget *dialog;
+  
+  /* remove tag from whole buffer */
+  gtk_text_buffer_get_bounds (buffer->buffer, &start, &end);
+  gtk_text_buffer_remove_tag (buffer->buffer,  buffer->found_text_tag,
+                              &start, &end );
+  
+  gtk_text_buffer_get_iter_at_mark (buffer->buffer, &iter,
+                                    gtk_text_buffer_get_mark (buffer->buffer,
+                                                              "insert"));
+
+
+  char_len = g_utf8_strlen (str, -1);
+
+  if (char_len > 0)
+    {
+      while (gtk_text_iter_forward_search (&iter, str, TRUE, FALSE))
+        {
+          GtkTextIter end = iter;
+          
+          gtk_text_iter_forward_chars (&end, char_len);
+          
+          gtk_text_buffer_apply_tag (buffer->buffer, buffer->found_text_tag,
+                                     &iter, &end);
+
+          iter = end;
+          
+          ++i;
+        }
+    }
+  
+  dialog = gtk_message_dialog_new (GTK_WINDOW (view->window),
+                                   GTK_MESSAGE_INFO,
+                                   GTK_BUTTONS_OK,
+                                   GTK_DIALOG_DESTROY_WITH_PARENT,
+                                   "%d strings found and marked in red",
+                                   i);
+
+  gtk_signal_connect_object (GTK_OBJECT (dialog),
+                             "response",
+                             GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                             GTK_OBJECT (dialog));
+  
+  gtk_widget_show (dialog);
+}
+
 static void
 buffer_ref (Buffer *buffer)
 {
@@ -1137,7 +1334,7 @@ close_view (View *view)
   g_free (view);
   
   if (!views)
-    gtk_main_quit();
+    gtk_main_quit ();
 }
 
 static void
@@ -1178,7 +1375,7 @@ create_view (Buffer *buffer)
   gtk_object_set_data (GTK_OBJECT (view->window), "view", view);
   
   gtk_signal_connect (GTK_OBJECT (view->window), "delete_event",
-                     GTK_SIGNAL_FUNC(delete_event_cb), NULL);
+                     GTK_SIGNAL_FUNC (delete_event_cb), NULL);
 
   view->accel_group = gtk_accel_group_new ();
   view->item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", view->accel_group);
@@ -1195,8 +1392,8 @@ create_view (Buffer *buffer)
                      gtk_item_factory_get_widget (view->item_factory, "<main>"),
                      FALSE, FALSE, 0);
   
-  sw = gtk_scrolled_window_new(NULL, NULL);
-  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
+  sw = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
                                  GTK_POLICY_AUTOMATIC,
                                  GTK_POLICY_AUTOMATIC);
 
@@ -1204,11 +1401,11 @@ create_view (Buffer *buffer)
   gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view->text_view), GTK_WRAPMODE_WORD);
 
   gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
-  gtk_container_add(GTK_CONTAINER(sw), view->text_view);
+  gtk_container_add (GTK_CONTAINER (sw), view->text_view);
 
   gtk_window_set_default_size (GTK_WINDOW (view->window), 500, 500);
 
-  gtk_widget_grab_focus(view->text_view);
+  gtk_widget_grab_focus (view->text_view);
 
   view_set_title (view);
   view_init_menus (view);
@@ -1218,14 +1415,15 @@ create_view (Buffer *buffer)
 }
 
 int
-main(int argc, char** argv)
+main (int argc, char** argv)
 {
   Buffer *buffer;
   View *view;
   int i;
   
-  gtk_init(&argc, &argv);
-
+  gtk_init (&argc, &argv);
+  gdk_rgb_init (); /* FIXME remove this */
+  
   buffer = create_buffer ();
   view = create_view (buffer);
   buffer_unref (buffer);
@@ -1254,7 +1452,7 @@ main(int argc, char** argv)
     }
   pop_active_window ();
   
-  gtk_main();
+  gtk_main ();
 
   return 0;
 }
index 884ed0f887b8cbeff1dd16f846a092edc78b3477..8047dc62df3adb4d3d55c26764ce5dc4c40cfd5c 100644 (file)
@@ -5,72 +5,72 @@
 #include <gtk/gtk.h>
 #include "gtktextbtree.h"
 
-static void fill_buffer(GtkTextBuffer *buffer);
+static void fill_buffer (GtkTextBuffer *buffer);
 
-static void run_tests(GtkTextBuffer *buffer);
+static void run_tests (GtkTextBuffer *buffer);
 
 int
-main(int argc, char** argv)
+main (int argc, char** argv)
 {
   GtkTextBuffer *buffer;
   int n;
   gunichar ch;
   GtkTextIter start, end;
   
-  gtk_init(&argc, &argv);
+  gtk_init (&argc, &argv);
 
   /* Check UTF8 unknown char thing */
-  g_assert(g_utf8_strlen (gtk_text_unknown_char_utf8, 3) == 1);
+  g_assert (g_utf8_strlen (gtk_text_unknown_char_utf8, 3) == 1);
   ch = g_utf8_get_char (gtk_text_unknown_char_utf8);
-  g_assert(ch == gtk_text_unknown_char);
+  g_assert (ch == gtk_text_unknown_char);
   
   /* First, we turn on btree debugging. */
   gtk_debug_flags |= GTK_DEBUG_TEXT;
 
   /* Create a buffer */
-  buffer = gtk_text_buffer_new(NULL);
+  buffer = gtk_text_buffer_new (NULL);
 
   /* Check that buffer starts with one empty line and zero chars */
   
-  n = gtk_text_buffer_get_line_count(buffer);
+  n = gtk_text_buffer_get_line_count (buffer);
   if (n != 1)
-    g_error("%d lines, expected 1", n);
+    g_error ("%d lines, expected 1", n);
   
-  n = gtk_text_buffer_get_char_count(buffer);
+  n = gtk_text_buffer_get_char_count (buffer);
   if (n != 1)
-    g_error("%d chars, expected 1", n);
+    g_error ("%d chars, expected 1", n);
   
   /* Run gruesome alien test suite on buffer */
-  run_tests(buffer);
+  run_tests (buffer);
   
   /* Put stuff in the buffer */
 
-  fill_buffer(buffer);
+  fill_buffer (buffer);
 
   /* Subject stuff-bloated buffer to further torment */
-  run_tests(buffer);
+  run_tests (buffer);
 
   /* Delete all stuff from the buffer */
-  gtk_text_buffer_get_bounds(buffer, &start, &end);
-  gtk_text_buffer_delete(buffer, &start, &end);
+  gtk_text_buffer_get_bounds (buffer, &start, &end);
+  gtk_text_buffer_delete (buffer, &start, &end);
 
   /* Check buffer for emptiness (note that a single
      empty line always remains in the buffer) */
-  n = gtk_text_buffer_get_line_count(buffer);
+  n = gtk_text_buffer_get_line_count (buffer);
   if (n != 1)
-    g_error("%d lines, expected 1", n);
+    g_error ("%d lines, expected 1", n);
   
-  n = gtk_text_buffer_get_char_count(buffer);
+  n = gtk_text_buffer_get_char_count (buffer);
   if (n != 1)
-    g_error("%d chars, expected 1", n);
+    g_error ("%d chars, expected 1", n);
 
-  run_tests(buffer);
+  run_tests (buffer);
   
   return 0;
 }
 
 static void
-run_tests(GtkTextBuffer *buffer)
+run_tests (GtkTextBuffer *buffer)
 {
   GtkTextIter iter;
   GtkTextIter start;
@@ -80,149 +80,151 @@ run_tests(GtkTextBuffer *buffer)
   gint num_chars;
   GtkTextMark *bar_mark;
   
-  gtk_text_buffer_get_bounds(buffer, &start, &end);
+  gtk_text_buffer_get_bounds (buffer, &start, &end);
   
   /* Check that walking the tree via chars and via indexes produces
    * the same number of indexable locations.
    */
-  num_chars = gtk_text_buffer_get_char_count(buffer);
+  num_chars = gtk_text_buffer_get_char_count (buffer);
   iter = start;
-  bar_mark = gtk_text_buffer_create_mark(buffer, "bar", &iter, FALSE);
+  bar_mark = gtk_text_buffer_create_mark (buffer, "bar", &iter, FALSE);
   i = 0;
   while (i < num_chars)
     {
       GtkTextIter current;
       GtkTextMark *foo_mark;
       
-      gtk_text_buffer_get_iter_at_char(buffer, &current, i);
+      gtk_text_buffer_get_iter_at_offset (buffer, &current, i);
 
-      if (!gtk_text_iter_equal(&iter, &current))
+      if (!gtk_text_iter_equal (&iter, &current))
         {
-          g_error("get_char_index didn't return current iter");
+          g_error ("get_char_index didn't return current iter");
         }
 
-      j = gtk_text_iter_get_char_index(&iter);
+      j = gtk_text_iter_get_offset (&iter);
 
       if (i != j)
         {
-          g_error("iter converted to %d not %d", j, i);
+          g_error ("iter converted to %d not %d", j, i);
         }
 
       /* get/set mark */
-      gtk_text_buffer_get_iter_at_mark(buffer, &mark, bar_mark);
+      gtk_text_buffer_get_iter_at_mark (buffer, &mark, bar_mark);
 
-      if (!gtk_text_iter_equal(&iter, &mark))
+      if (!gtk_text_iter_equal (&iter, &mark))
         {
-          gtk_text_iter_spew(&iter, "iter");
-          gtk_text_iter_spew(&mark, "mark");
-          g_error("Mark not moved to the right place.");
+          gtk_text_iter_spew (&iter, "iter");
+          gtk_text_iter_spew (&mark, "mark");
+          g_error ("Mark not moved to the right place.");
         }
       
-      foo_mark = gtk_text_buffer_create_mark(buffer, "foo", &iter, FALSE);
-      gtk_text_buffer_get_iter_at_mark(buffer, &mark, foo_mark);
-      gtk_text_buffer_delete_mark(buffer, foo_mark);
+      foo_mark = gtk_text_buffer_create_mark (buffer, "foo", &iter, FALSE);
+      gtk_text_buffer_get_iter_at_mark (buffer, &mark, foo_mark);
+      gtk_text_buffer_delete_mark (buffer, foo_mark);
       
-      if (!gtk_text_iter_equal(&iter, &mark))
+      if (!gtk_text_iter_equal (&iter, &mark))
         {
-          gtk_text_iter_spew(&iter, "iter");
-          gtk_text_iter_spew(&mark, "mark");
-          g_error("Mark not created in the right place.");
+          gtk_text_iter_spew (&iter, "iter");
+          gtk_text_iter_spew (&mark, "mark");
+          g_error ("Mark not created in the right place.");
         }
+
+      if (gtk_text_iter_is_last (&iter))
+        g_error ("iterators ran out before chars (offset %d of %d)",
+                 i, num_chars);
       
-      if (!gtk_text_iter_forward_char(&iter))
-        g_error("iterators ran out before chars");      
+      gtk_text_iter_next_char (&iter);
 
-      gtk_text_buffer_move_mark(buffer, bar_mark, &iter);
+      gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
       
       ++i;
     }
 
-  if (!gtk_text_iter_equal(&iter, &end))
-    g_error("Iterating over all chars didn't end with the end iter");
+  if (!gtk_text_iter_equal (&iter, &end))
+    g_error ("Iterating over all chars didn't end with the end iter");
 
   /* Do the tree-walk backward 
    */
-  num_chars = gtk_text_buffer_get_char_count(buffer);
-  gtk_text_buffer_get_iter_at_char(buffer, &iter, -1);
+  num_chars = gtk_text_buffer_get_char_count (buffer);
+  gtk_text_buffer_get_iter_at_offset (buffer, &iter, -1);
 
-  gtk_text_buffer_move_mark(buffer, bar_mark, &iter);
+  gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
   
   i = num_chars;
 
-  if (!gtk_text_iter_equal(&iter, &end))
-    g_error("iter at char -1 is not equal to the end iterator");
+  if (!gtk_text_iter_equal (&iter, &end))
+    g_error ("iter at char -1 is not equal to the end iterator");
   
   while (i >= 0)
     {
       GtkTextIter current;
       GtkTextMark *foo_mark;
       
-      gtk_text_buffer_get_iter_at_char(buffer, &current, i);
+      gtk_text_buffer_get_iter_at_offset (buffer, &current, i);
 
-      if (!gtk_text_iter_equal(&iter, &current))
+      if (!gtk_text_iter_equal (&iter, &current))
         {
-          g_error("get_char_index didn't return current iter while going backward");
+          g_error ("get_char_index didn't return current iter while going backward");
         }
-      j = gtk_text_iter_get_char_index(&iter);
+      j = gtk_text_iter_get_offset (&iter);
 
       if (i != j)
         {
-          g_error("going backward, iter converted to %d not %d", j, i);
+          g_error ("going backward, iter converted to %d not %d", j, i);
         }
 
       /* get/set mark */
-      gtk_text_buffer_get_iter_at_mark(buffer, &mark, bar_mark);
+      gtk_text_buffer_get_iter_at_mark (buffer, &mark, bar_mark);
 
-      if (!gtk_text_iter_equal(&iter, &mark))
+      if (!gtk_text_iter_equal (&iter, &mark))
         {
-          gtk_text_iter_spew(&iter, "iter");
-          gtk_text_iter_spew(&mark, "mark");
-          g_error("Mark not moved to the right place.");
+          gtk_text_iter_spew (&iter, "iter");
+          gtk_text_iter_spew (&mark, "mark");
+          g_error ("Mark not moved to the right place.");
         }
       
-      foo_mark = gtk_text_buffer_create_mark(buffer, "foo", &iter, FALSE);
-      gtk_text_buffer_get_iter_at_mark(buffer, &mark, foo_mark);
-      gtk_text_buffer_delete_mark(buffer, foo_mark);
+      foo_mark = gtk_text_buffer_create_mark (buffer, "foo", &iter, FALSE);
+      gtk_text_buffer_get_iter_at_mark (buffer, &mark, foo_mark);
+      gtk_text_buffer_delete_mark (buffer, foo_mark);
       
-      if (!gtk_text_iter_equal(&iter, &mark))
+      if (!gtk_text_iter_equal (&iter, &mark))
         {
-          gtk_text_iter_spew(&iter, "iter");
-          gtk_text_iter_spew(&mark, "mark");
-          g_error("Mark not created in the right place.");
+          gtk_text_iter_spew (&iter, "iter");
+          gtk_text_iter_spew (&mark, "mark");
+          g_error ("Mark not created in the right place.");
         }
       
       if (i > 0)
         {
-          if (!gtk_text_iter_backward_char(&iter))
-            g_error("iterators ran out before char indexes");
+          if (!gtk_text_iter_prev_char (&iter))
+            g_error ("iterators ran out before char indexes");
 
-          gtk_text_buffer_move_mark(buffer, bar_mark, &iter);
+          gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
         }
       else
         {
-          if (gtk_text_iter_backward_char(&iter))
-            g_error("went backward from 0?");
+          if (gtk_text_iter_prev_char (&iter))
+            g_error ("went backward from 0?");
         }
       
       --i;
     }
   
-  if (!gtk_text_iter_equal(&iter, &start))
-    g_error("Iterating backward over all chars didn't end with the start iter");
+  if (!gtk_text_iter_equal (&iter, &start))
+    g_error ("Iterating backward over all chars didn't end with the start iter");
 
   /*
    * Check that get_line_count returns the same number of lines
    * as walking the tree by line
    */
   i = 1; /* include current (first) line */
-  gtk_text_buffer_get_iter_at_line(buffer, &iter, 0);
-  while (gtk_text_iter_forward_line(&iter))
+  gtk_text_buffer_get_iter_at_line (buffer, &iter, 0);
+  while (gtk_text_iter_forward_line (&iter))
     ++i;
-
-  /* Add 1 to the line count, because 'i' counts the end-iterator line */
-  if (i != gtk_text_buffer_get_line_count(buffer) + 1)
-    g_error("Counted %d lines, buffer has %d", i,
-            gtk_text_buffer_get_line_count(buffer) + 1);
+  
+  if (i != gtk_text_buffer_get_line_count (buffer))
+    g_error ("Counted %d lines, buffer has %d", i,
+            gtk_text_buffer_get_line_count (buffer));
 }
 
 
@@ -252,7 +254,7 @@ static char  *book_closed_xpm[] = {
 "                "};
 
 static void
-fill_buffer(GtkTextBuffer *buffer)
+fill_buffer (GtkTextBuffer *buffer)
 {
   GtkTextTag *tag;
   GdkColor color, color2;
@@ -262,65 +264,65 @@ fill_buffer(GtkTextBuffer *buffer)
   GdkBitmap *mask;
   int i;
   
-  tag = gtk_text_buffer_create_tag(buffer, "fg_blue");
+  tag = gtk_text_buffer_create_tag (buffer, "fg_blue");
 
   color.red = color.green = 0;
   color.blue = 0xffff;
   color2.red = 0xfff;
   color2.blue = 0x0;
   color2.green = 0;
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                  "foreground_gdk", &color,
                  "background_gdk", &color2,
                  "font", "-*-courier-bold-r-*-*-30-*-*-*-*-*-*-*",
                  NULL);
 
-  tag = gtk_text_buffer_create_tag(buffer, "fg_red");
+  tag = gtk_text_buffer_create_tag (buffer, "fg_red");
 
   color.blue = color.green = 0;
   color.red = 0xffff;
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                  "offset", -4,
                  "foreground_gdk", &color,
                  NULL);
 
-  tag = gtk_text_buffer_create_tag(buffer, "bg_green");
+  tag = gtk_text_buffer_create_tag (buffer, "bg_green");
 
   color.blue = color.red = 0;
   color.green = 0xffff;
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                  "background_gdk", &color,
                  "font", "-*-courier-bold-r-*-*-10-*-*-*-*-*-*-*",
                  NULL);
 
   pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL,
-                                                  gtk_widget_get_default_colormap(),
+                                                  gtk_widget_get_default_colormap (),
                                                   &mask,
                                                   NULL, book_closed_xpm);
   
-  g_assert(pixmap != NULL);
+  g_assert (pixmap != NULL);
   
   i = 0;
   while (i < 10)
     {
       gchar *str;
 
-      gtk_text_buffer_get_iter_at_char(buffer, &iter, 0);
+      gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
       
       gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
 
-      gtk_text_buffer_get_iter_at_char(buffer, &iter, 1);
+      gtk_text_buffer_get_iter_at_offset (buffer, &iter, 1);
       
       gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
       
-      str = g_strdup_printf("%d Hello World!\nwoo woo woo woo woo woo woo woo\n",
+      str = g_strdup_printf ("%d Hello World!\nwoo woo woo woo woo woo woo woo\n",
                             i);
       
-      gtk_text_buffer_insert(buffer, &iter, str, -1);
+      gtk_text_buffer_insert (buffer, &iter, str, -1);
 
-      g_free(str);
+      g_free (str);
       
-      gtk_text_buffer_insert(buffer, &iter,
+      gtk_text_buffer_insert (buffer, &iter,
                               "(Hello World!)\nfoo foo Hello this is some text we are using to text word wrap. It has punctuation! gee; blah - hmm, great.\nnew line\n\n"
                               /* This is UTF8 stuff, Emacs doesn't
                                  really know how to display it */
@@ -330,64 +332,64 @@ fill_buffer(GtkTextBuffer *buffer)
       gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
       gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
       
-      gtk_text_buffer_get_iter_at_char(buffer, &iter, 4);
+      gtk_text_buffer_get_iter_at_offset (buffer, &iter, 4);
       
       gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
 
-      gtk_text_buffer_get_iter_at_char(buffer, &iter, 7);
+      gtk_text_buffer_get_iter_at_offset (buffer, &iter, 7);
       
       gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
 
-      gtk_text_buffer_get_iter_at_char(buffer, &iter, 8);
+      gtk_text_buffer_get_iter_at_offset (buffer, &iter, 8);
       
       gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
 
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter, 0, 8);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 0, 8);
       iter2 = iter;
-      gtk_text_iter_forward_chars(&iter2, 10);
+      gtk_text_iter_forward_chars (&iter2, 10);
 
-      gtk_text_buffer_apply_tag(buffer, "fg_blue", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
 
-      gtk_text_iter_forward_chars(&iter, 7);
-      gtk_text_iter_forward_chars(&iter2, 10);
+      gtk_text_iter_forward_chars (&iter, 7);
+      gtk_text_iter_forward_chars (&iter2, 10);
       
-      gtk_text_buffer_apply_tag(buffer, "bg_green", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "bg_green", &iter, &iter2);
 
-      gtk_text_iter_forward_chars(&iter, 12);
-      gtk_text_iter_forward_chars(&iter2, 10);
+      gtk_text_iter_forward_chars (&iter, 12);
+      gtk_text_iter_forward_chars (&iter2, 10);
       
-      gtk_text_buffer_apply_tag(buffer, "bg_green", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "bg_green", &iter, &iter2);
 
-      gtk_text_iter_forward_chars(&iter, 10);
-      gtk_text_iter_forward_chars(&iter2, 15);
+      gtk_text_iter_forward_chars (&iter, 10);
+      gtk_text_iter_forward_chars (&iter2, 15);
       
-      gtk_text_buffer_apply_tag(buffer, "fg_red", &iter, &iter2);
-      gtk_text_buffer_apply_tag(buffer, "fg_blue", &iter, &iter2);      
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);      
 
-      gtk_text_iter_forward_chars(&iter, 20);
-      gtk_text_iter_forward_chars(&iter2, 20);
+      gtk_text_iter_forward_chars (&iter, 20);
+      gtk_text_iter_forward_chars (&iter2, 20);
       
-      gtk_text_buffer_apply_tag(buffer, "fg_red", &iter, &iter2);
-      gtk_text_buffer_apply_tag(buffer, "fg_blue", &iter, &iter2);      
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);      
 
-      gtk_text_iter_backward_chars(&iter, 25);
-      gtk_text_iter_forward_chars(&iter2, 5);
+      gtk_text_iter_backward_chars (&iter, 25);
+      gtk_text_iter_forward_chars (&iter2, 5);
       
-      gtk_text_buffer_apply_tag(buffer, "fg_red", &iter, &iter2);
-      gtk_text_buffer_apply_tag(buffer, "fg_blue", &iter, &iter2);      
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);      
 
-      gtk_text_iter_forward_chars(&iter, 15);
-      gtk_text_iter_backward_chars(&iter2, 10);
+      gtk_text_iter_forward_chars (&iter, 15);
+      gtk_text_iter_backward_chars (&iter2, 10);
 
-      gtk_text_buffer_remove_tag(buffer, "fg_red", &iter, &iter2);
-      gtk_text_buffer_remove_tag(buffer, "fg_blue", &iter, &iter2);      
+      gtk_text_buffer_remove_tag_by_name (buffer, "fg_red", &iter, &iter2);
+      gtk_text_buffer_remove_tag_by_name (buffer, "fg_blue", &iter, &iter2);      
       
       ++i;
     }
 
-  gdk_pixmap_unref(pixmap);
+  gdk_pixmap_unref (pixmap);
   if (mask)
-    gdk_bitmap_unref(mask);
+    gdk_bitmap_unref (mask);
 }
 
 
index fad48f0399bb171477f6f071e04a014b38878be9..bbff4d00aeddde7bf1816d8facde2807ee78bb31 100644 (file)
@@ -20,6 +20,8 @@ struct _Buffer
   GtkTextBuffer *buffer;
   char *filename;
   gint untitled_serial;
+  GtkTextTag *not_editable_tag;
+  GtkTextTag *found_text_tag;
 };
 
 struct _View
@@ -41,6 +43,9 @@ static gboolean save_buffer        (Buffer *buffer);
 static gboolean save_as_buffer     (Buffer *buffer);
 static char *   buffer_pretty_name (Buffer *buffer);
 static void     buffer_filename_set (Buffer *buffer);
+static void     buffer_search_forward (Buffer *buffer,
+                                       const char *str,
+                                       View *view);
 
 static View *view_from_widget (GtkWidget *widget);
 
@@ -290,14 +295,14 @@ msgbox_run (GtkWindow  *parent,
  * Example buffer filling code
  */
 static gint
-blink_timeout(gpointer data)
+blink_timeout (gpointer data)
 {
   GtkTextTag *tag;
   static gboolean flip = FALSE;
   
-  tag = GTK_TEXT_TAG(data);
+  tag = GTK_TEXT_TAG (data);
 
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                  "foreground", flip ? "blue" : "purple",
                  NULL);
 
@@ -307,42 +312,46 @@ blink_timeout(gpointer data)
 }
 
 static gint
-tag_event_handler(GtkTextTag *tag, GtkWidget *widget, GdkEvent *event,
+tag_event_handler (GtkTextTag *tag, GtkWidget *widget, GdkEvent *event,
                   const GtkTextIter *iter, gpointer user_data)
 {
   gint char_index;
 
-  char_index = gtk_text_iter_get_char_index(iter);
+  char_index = gtk_text_iter_get_offset (iter);
   
   switch (event->type)
     {
     case GDK_MOTION_NOTIFY:
-      printf("Motion event at char %d tag `%s'\n",
+      printf ("Motion event at char %d tag `%s'\n",
              char_index, tag->name);
       break;
         
     case GDK_BUTTON_PRESS:
-      printf("Button press at char %d tag `%s'\n",
+      printf ("Button press at char %d tag `%s'\n",
              char_index, tag->name);
       break;
         
     case GDK_2BUTTON_PRESS:
-      printf("Double click at char %d tag `%s'\n",
+      printf ("Double click at char %d tag `%s'\n",
              char_index, tag->name);
       break;
         
     case GDK_3BUTTON_PRESS:
-      printf("Triple click at char %d tag `%s'\n",
+      printf ("Triple click at char %d tag `%s'\n",
              char_index, tag->name);
       break;
         
     case GDK_BUTTON_RELEASE:
-      printf("Button release at char %d tag `%s'\n",
+      printf ("Button release at char %d tag `%s'\n",
              char_index, tag->name);
       break;
         
     case GDK_KEY_PRESS:
     case GDK_KEY_RELEASE:
+      printf ("Key event at char %d tag `%s'\n",
+              char_index, tag->name);
+      break;
+      
     case GDK_ENTER_NOTIFY:
     case GDK_LEAVE_NOTIFY:
     case GDK_PROPERTY_NOTIFY:
@@ -365,12 +374,12 @@ tag_event_handler(GtkTextTag *tag, GtkWidget *widget, GdkEvent *event,
 }
 
 static void
-setup_tag(GtkTextTag *tag)
+setup_tag (GtkTextTag *tag)
 {
 
-  gtk_signal_connect(GTK_OBJECT(tag),
+  gtk_signal_connect (GTK_OBJECT (tag),
                      "event",
-                     GTK_SIGNAL_FUNC(tag_event_handler),
+                     GTK_SIGNAL_FUNC (tag_event_handler),
                      NULL);
 }
 
@@ -413,77 +422,77 @@ fill_example_buffer (GtkTextBuffer *buffer)
   int i;
   char *str;
   
-  tag = gtk_text_buffer_create_tag(buffer, "fg_blue");
+  tag = gtk_text_buffer_create_tag (buffer, "fg_blue");
 
-  /*       gtk_timeout_add(1000, blink_timeout, tag); */
+  /*       gtk_timeout_add (1000, blink_timeout, tag); */
       
-  setup_tag(tag);
+  setup_tag (tag);
   
   color.red = color.green = 0;
   color.blue = 0xffff;
   color2.red = 0xfff;
   color2.blue = 0x0;
   color2.green = 0;
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                 "foreground_gdk", &color,
                 "background_gdk", &color2,
                 "font", "Sans 24",
                 NULL);
 
-  tag = gtk_text_buffer_create_tag(buffer, "fg_red");
+  tag = gtk_text_buffer_create_tag (buffer, "fg_red");
 
-  setup_tag(tag);
+  setup_tag (tag);
       
   color.blue = color.green = 0;
   color.red = 0xffff;
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                 "offset", -4,
                 "foreground_gdk", &color,
                 NULL);
 
-  tag = gtk_text_buffer_create_tag(buffer, "bg_green");
+  tag = gtk_text_buffer_create_tag (buffer, "bg_green");
 
-  setup_tag(tag);
+  setup_tag (tag);
       
   color.blue = color.red = 0;
   color.green = 0xffff;
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                 "background_gdk", &color,
                 "font", "Sans 10",
                 NULL);
 
-  tag = gtk_text_buffer_create_tag(buffer, "overstrike");
+  tag = gtk_text_buffer_create_tag (buffer, "overstrike");
 
-  setup_tag(tag);
+  setup_tag (tag);
       
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                 "overstrike", TRUE,
                 NULL);
 
 
-  tag = gtk_text_buffer_create_tag(buffer, "underline");
+  tag = gtk_text_buffer_create_tag (buffer, "underline");
 
-  setup_tag(tag);
+  setup_tag (tag);
       
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                 "underline", PANGO_UNDERLINE_SINGLE,
                 NULL);
 
-  setup_tag(tag);
+  setup_tag (tag);
       
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                 "underline", PANGO_UNDERLINE_SINGLE,
                 NULL);
 
-  tag = gtk_text_buffer_create_tag(buffer, "centered");
+  tag = gtk_text_buffer_create_tag (buffer, "centered");
       
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                 "justify", GTK_JUSTIFY_CENTER,
                 NULL);
 
-  tag = gtk_text_buffer_create_tag(buffer, "rtl_quote");
+  tag = gtk_text_buffer_create_tag (buffer, "rtl_quote");
       
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                 "wrap_mode", GTK_WRAPMODE_WORD,
                 "direction", GTK_TEXT_DIR_RTL,
                 "left_wrapped_line_margin", 20,
@@ -492,31 +501,31 @@ fill_example_buffer (GtkTextBuffer *buffer)
                 NULL);
   
   pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL,
-                                                 gtk_widget_get_default_colormap(),
+                                                 gtk_widget_get_default_colormap (),
                                                  &mask,
                                                  NULL, book_closed_xpm);
   
-  g_assert(pixmap != NULL);
+  g_assert (pixmap != NULL);
   
   i = 0;
   while (i < 100)
     {
       GtkTextMark * temp_mark;
       
-      gtk_text_buffer_get_iter_at_char(buffer, &iter, 0);
+      gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
           
       gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
           
-      str = g_strdup_printf("%d Hello World! blah blah blah blah blah blah blah blah blah blah blah blah\nwoo woo woo woo woo woo woo woo woo woo woo woo woo woo woo\n",
+      str = g_strdup_printf ("%d Hello World! blah blah blah blah blah blah blah blah blah blah blah blah\nwoo woo woo woo woo woo woo woo woo woo woo woo woo woo woo\n",
                            i);
       
-      gtk_text_buffer_insert(buffer, &iter, str, -1);
+      gtk_text_buffer_insert (buffer, &iter, str, -1);
 
-      g_free(str);
+      g_free (str);
       
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter, 0, 5);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 0, 5);
           
-      gtk_text_buffer_insert(buffer, &iter,
+      gtk_text_buffer_insert (buffer, &iter,
                             "(Hello World!)\nfoo foo Hello this is some text we are using to text word wrap. It has punctuation! gee; blah - hmm, great.\nnew line with a significant quantity of text on it. This line really does contain some text. More text! More text! More text!\n"
                             /* This is UTF8 stuff, Emacs doesn't
                                really know how to display it */
@@ -526,59 +535,59 @@ fill_example_buffer (GtkTextBuffer *buffer)
         gtk_text_buffer_create_mark (buffer, "tmp_mark", &iter, TRUE);
 
 #if 1
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter, 0, 6);
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter2, 0, 13);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 0, 6);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter2, 0, 13);
 
-      gtk_text_buffer_apply_tag(buffer, "fg_blue", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
 
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter, 1, 10);
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter2, 1, 16);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 1, 10);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter2, 1, 16);
 
-      gtk_text_buffer_apply_tag(buffer, "underline", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "underline", &iter, &iter2);
 
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter, 1, 14);
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter2, 1, 24);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 1, 14);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter2, 1, 24);
 
-      gtk_text_buffer_apply_tag(buffer, "overstrike", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "overstrike", &iter, &iter2);
           
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter, 0, 9);
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter2, 0, 16);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 0, 9);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter2, 0, 16);
 
-      gtk_text_buffer_apply_tag(buffer, "bg_green", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "bg_green", &iter, &iter2);
   
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter, 4, 2);
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter2, 4, 10);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 4, 2);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter2, 4, 10);
 
-      gtk_text_buffer_apply_tag(buffer, "bg_green", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "bg_green", &iter, &iter2);
 
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter, 4, 8);
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter2, 4, 15);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 4, 8);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter2, 4, 15);
 
-      gtk_text_buffer_apply_tag(buffer, "fg_red", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
 #endif
 
       gtk_text_buffer_get_iter_at_mark (buffer, &iter, temp_mark);
       gtk_text_buffer_insert (buffer, &iter, "Centered text!\n", -1);
          
       gtk_text_buffer_get_iter_at_mark (buffer, &iter2, temp_mark);
-      gtk_text_buffer_apply_tag (buffer, "centered", &iter2, &iter);
+      gtk_text_buffer_apply_tag_by_name (buffer, "centered", &iter2, &iter);
 
       gtk_text_buffer_move_mark (buffer, temp_mark, &iter);
       gtk_text_buffer_insert (buffer, &iter, "Word wrapped, Right-to-left Quote\n", -1);
       gtk_text_buffer_insert (buffer, &iter, "وقد بدأ ثلاث من أكثر المؤسسات تقدما في شبكة اكسيون برامجها كمنظمات لا تسعى للربح، ثم تحولت في السنوات الخمس الماضية إلى مؤسسات مالية منظمة، وباتت جزءا من النظام المالي في بلدانها، ولكنها تتخصص في خدمة قطاع المشروعات الصغيرة. وأحد أكثر هذه المؤسسات نجاحا هو »بانكوسول« في بوليفيا.\n", -1);
       gtk_text_buffer_get_iter_at_mark (buffer, &iter2, temp_mark);
-      gtk_text_buffer_apply_tag (buffer, "rtl_quote", &iter2, &iter);
+      gtk_text_buffer_apply_tag_by_name (buffer, "rtl_quote", &iter2, &iter);
          
       ++i;
     }
 
-  gdk_pixmap_unref(pixmap);
+  gdk_pixmap_unref (pixmap);
   if (mask)
-    gdk_bitmap_unref(mask);
+    gdk_bitmap_unref (mask);
   
-  printf("%d lines %d chars\n",
-        gtk_text_buffer_get_line_count(buffer),
-        gtk_text_buffer_get_char_count(buffer));
+  printf ("%d lines %d chars\n",
+        gtk_text_buffer_get_line_count (buffer),
+        gtk_text_buffer_get_char_count (buffer));
 
   gtk_text_buffer_set_modified (buffer, FALSE);
 }
@@ -591,7 +600,7 @@ fill_file_buffer (GtkTextBuffer *buffer, const char *filename)
   gint remaining = 0;
   GtkTextIter iter, end;
 
-  f = fopen(filename, "r");
+  f = fopen (filename, "r");
   
   if (f == NULL)
     {
@@ -602,7 +611,7 @@ fill_file_buffer (GtkTextBuffer *buffer, const char *filename)
       return FALSE;
     }
   
-  gtk_text_buffer_get_iter_at_char(buffer, &iter, 0);
+  gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
   while (!feof (f))
     {
       gint count;
@@ -650,7 +659,7 @@ fill_file_buffer (GtkTextBuffer *buffer, const char *filename)
 }
 
 static gint
-delete_event_cb(GtkWidget *window, GdkEventAny *event, gpointer data)
+delete_event_cb (GtkWidget *window, GdkEventAny *event, gpointer data)
 {
   View *view = view_from_widget (window);
 
@@ -801,7 +810,7 @@ do_exit    (gpointer             callback_data,
       tmp_list = tmp_list->next;
     }
 
-  gtk_main_quit();
+  gtk_main_quit ();
   pop_active_window ();
 }
 
@@ -839,6 +848,118 @@ do_direction_changed (gpointer             callback_data,
   gtk_widget_queue_resize (view->text_view);
 }
 
+static void
+do_editable_changed (gpointer callback_data,
+                     guint callback_action,
+                     GtkWidget *widget)
+{
+  View *view = view_from_widget (widget);
+
+  gtk_text_view_set_editable (GTK_TEXT_VIEW (view->text_view), callback_action);
+}
+
+static void
+do_cursor_visible_changed (gpointer callback_data,
+                           guint callback_action,
+                           GtkWidget *widget)
+{
+  View *view = view_from_widget (widget);
+
+  gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view->text_view), callback_action);
+}
+
+static void
+do_apply_editable (gpointer callback_data,
+                   guint callback_action,
+                   GtkWidget *widget)
+{
+  View *view = view_from_widget (widget);
+  GtkTextIter start;
+  GtkTextIter end;
+  
+  if (gtk_text_buffer_get_selection_bounds (view->buffer->buffer,
+                                            &start, &end))
+    {
+      if (callback_action)
+        {
+          gtk_text_buffer_remove_tag (view->buffer->buffer,
+                                      view->buffer->not_editable_tag,
+                                      &start, &end);
+        }
+      else
+        {
+          gtk_text_buffer_apply_tag (view->buffer->buffer,
+                                     view->buffer->not_editable_tag,
+                                     &start, &end);
+        }
+    }
+}
+
+static void
+dialog_response_callback (GtkWidget *dialog, gint response_id, gpointer data)
+{
+  GtkTextBuffer *buffer;
+  View *view = data;
+  GtkTextIter start, end;
+  gchar *search_string;
+  
+  buffer = gtk_object_get_data (GTK_OBJECT (dialog), "buffer");
+
+  gtk_text_buffer_get_bounds (buffer, &start, &end);
+
+  /* Remove trailing newline */
+  gtk_text_iter_prev_char (&end);
+  
+  search_string = gtk_text_iter_get_text (&start, &end);
+
+  printf ("Searching for `%s'\n", search_string);
+  
+  buffer_search_forward (view->buffer, search_string, view);
+
+  g_free (search_string);
+  
+  gtk_widget_destroy (dialog);
+}
+
+static void
+do_search (gpointer callback_data,
+           guint callback_action,
+           GtkWidget *widget)
+{
+  View *view = view_from_widget (widget);
+  GtkWidget *dialog;
+  GtkWidget *search_text;
+  GtkTextBuffer *buffer;
+  
+  dialog = gtk_dialog_new_with_buttons ("Search",
+                                        GTK_WINDOW (view->window),
+                                        GTK_DIALOG_DESTROY_WITH_PARENT,
+                                        GTK_STOCK_BUTTON_CLOSE,
+                                        GTK_RESPONSE_NONE, NULL);
+
+  buffer = gtk_text_buffer_new (NULL);
+
+  /* FIXME memory leak once buffer is a GObject */
+  search_text = gtk_text_view_new_with_buffer (buffer);
+
+  gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->vbox),
+                    search_text,
+                    TRUE, TRUE, 0);
+
+  gtk_object_set_data (GTK_OBJECT (dialog), "buffer", buffer);
+  
+  gtk_signal_connect (GTK_OBJECT (dialog),
+                      "response",
+                      GTK_SIGNAL_FUNC (dialog_response_callback),
+                      view);
+
+  gtk_widget_show (search_text);
+
+  gtk_widget_grab_focus (search_text);
+  
+  gtk_widget_show_all (dialog);
+}
+
 static void
 view_init_menus (View *view)
 {
@@ -889,13 +1010,26 @@ static GtkItemFactoryEntry menu_items[] =
   { "/File/_Close",     "<control>W" , do_close,    0, NULL },
   { "/File/E_xit",      "<control>Q" , do_exit,     0, NULL },
 
+  { "/_Edit", NULL, 0, 0, "<Branch>" },
+  { "/Edit/Find...", NULL, do_search, 0, NULL },
+
   { "/_Settings",        NULL,         0,                0, "<Branch>" },
   { "/Settings/Wrap _Off",   NULL,      do_wrap_changed,  GTK_WRAPMODE_NONE, "<RadioItem>" },
   { "/Settings/Wrap _Words", NULL,      do_wrap_changed,  GTK_WRAPMODE_WORD, "/Settings/Wrap Off" },
   { "/Settings/sep1",        NULL,      0,                0, "<Separator>" },
+  { "/Settings/Editable", NULL,      do_editable_changed,  TRUE, "<RadioItem>" },
+  { "/Settings/Not editable",    NULL,      do_editable_changed,  FALSE, "/Settings/Editable" },
+  { "/Settings/sep1",        NULL,      0,                0, "<Separator>" },
+
+  { "/Settings/Cursor visible",    NULL,      do_cursor_visible_changed,  TRUE, "<RadioItem>" },
+  { "/Settings/Cursor not visible", NULL,      do_cursor_visible_changed,  FALSE, "/Settings/Cursor visible" },
+  { "/Settings/sep1",        NULL,      0,                0, "<Separator>" },
+  
   { "/Settings/Left-to-Right", NULL,    do_direction_changed,  GTK_TEXT_DIR_LTR, "<RadioItem>" },
   { "/Settings/Right-to-Left", NULL,    do_direction_changed,  GTK_TEXT_DIR_RTL, "/Settings/Left-to-Right" },
-  
+  { "/_Attributes",      NULL,         0,                0, "<Branch>" },
+  { "/Attributes/Editable",      NULL,         do_apply_editable, TRUE, NULL },
+  { "/Attributes/Not editable",          NULL,         do_apply_editable, FALSE, NULL },
   { "/_Test",           NULL,         0,           0, "<Branch>" },
   { "/Test/_Example",           NULL,         do_example,  0, NULL },
 };
@@ -938,7 +1072,7 @@ save_buffer (Buffer *buffer)
     }
   else
     {
-      gtk_text_buffer_get_iter_at_char (buffer->buffer, &start, 0);
+      gtk_text_buffer_get_iter_at_offset (buffer->buffer, &start, 0);
       gtk_text_buffer_get_last_iter (buffer->buffer, &end);
   
       chars = gtk_text_buffer_get_slice (buffer->buffer, &start, &end, FALSE);
@@ -988,7 +1122,7 @@ save_as_ok_func (const char *filename, gpointer data)
     {
       struct stat statbuf;
 
-      if (stat(filename, &statbuf) == 0)
+      if (stat (filename, &statbuf) == 0)
        {
          gchar *err = g_strdup_printf ("Ovewrite existing file '%s'?", filename);
          gint result = msgbox_run (NULL, err, "Yes", "No", NULL, 1);
@@ -1061,6 +1195,15 @@ create_buffer (void)
   buffer->filename = NULL;
   buffer->untitled_serial = -1;
 
+  buffer->not_editable_tag = gtk_text_buffer_create_tag (buffer->buffer, NULL);
+  gtk_object_set (GTK_OBJECT (buffer->not_editable_tag),
+                  "editable", FALSE,
+                  "foreground", "purple", NULL);
+
+  buffer->found_text_tag = gtk_text_buffer_create_tag (buffer->buffer, NULL);
+  gtk_object_set (GTK_OBJECT (buffer->found_text_tag),
+                  "foreground", "red", NULL);
+  
   buffers = g_slist_prepend (buffers, buffer);
   
   return buffer;
@@ -1107,6 +1250,60 @@ buffer_filename_set (Buffer *buffer)
     }
 }
 
+static void
+buffer_search_forward (Buffer *buffer, const char *str,
+                       View *view)
+{
+  GtkTextIter iter;
+  GtkTextIter start, end;
+  gint char_len;
+  int i = 0;
+  GtkWidget *dialog;
+  
+  /* remove tag from whole buffer */
+  gtk_text_buffer_get_bounds (buffer->buffer, &start, &end);
+  gtk_text_buffer_remove_tag (buffer->buffer,  buffer->found_text_tag,
+                              &start, &end );
+  
+  gtk_text_buffer_get_iter_at_mark (buffer->buffer, &iter,
+                                    gtk_text_buffer_get_mark (buffer->buffer,
+                                                              "insert"));
+
+
+  char_len = g_utf8_strlen (str, -1);
+
+  if (char_len > 0)
+    {
+      while (gtk_text_iter_forward_search (&iter, str, TRUE, FALSE))
+        {
+          GtkTextIter end = iter;
+          
+          gtk_text_iter_forward_chars (&end, char_len);
+          
+          gtk_text_buffer_apply_tag (buffer->buffer, buffer->found_text_tag,
+                                     &iter, &end);
+
+          iter = end;
+          
+          ++i;
+        }
+    }
+  
+  dialog = gtk_message_dialog_new (GTK_WINDOW (view->window),
+                                   GTK_MESSAGE_INFO,
+                                   GTK_BUTTONS_OK,
+                                   GTK_DIALOG_DESTROY_WITH_PARENT,
+                                   "%d strings found and marked in red",
+                                   i);
+
+  gtk_signal_connect_object (GTK_OBJECT (dialog),
+                             "response",
+                             GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                             GTK_OBJECT (dialog));
+  
+  gtk_widget_show (dialog);
+}
+
 static void
 buffer_ref (Buffer *buffer)
 {
@@ -1137,7 +1334,7 @@ close_view (View *view)
   g_free (view);
   
   if (!views)
-    gtk_main_quit();
+    gtk_main_quit ();
 }
 
 static void
@@ -1178,7 +1375,7 @@ create_view (Buffer *buffer)
   gtk_object_set_data (GTK_OBJECT (view->window), "view", view);
   
   gtk_signal_connect (GTK_OBJECT (view->window), "delete_event",
-                     GTK_SIGNAL_FUNC(delete_event_cb), NULL);
+                     GTK_SIGNAL_FUNC (delete_event_cb), NULL);
 
   view->accel_group = gtk_accel_group_new ();
   view->item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", view->accel_group);
@@ -1195,8 +1392,8 @@ create_view (Buffer *buffer)
                      gtk_item_factory_get_widget (view->item_factory, "<main>"),
                      FALSE, FALSE, 0);
   
-  sw = gtk_scrolled_window_new(NULL, NULL);
-  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
+  sw = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
                                  GTK_POLICY_AUTOMATIC,
                                  GTK_POLICY_AUTOMATIC);
 
@@ -1204,11 +1401,11 @@ create_view (Buffer *buffer)
   gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view->text_view), GTK_WRAPMODE_WORD);
 
   gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
-  gtk_container_add(GTK_CONTAINER(sw), view->text_view);
+  gtk_container_add (GTK_CONTAINER (sw), view->text_view);
 
   gtk_window_set_default_size (GTK_WINDOW (view->window), 500, 500);
 
-  gtk_widget_grab_focus(view->text_view);
+  gtk_widget_grab_focus (view->text_view);
 
   view_set_title (view);
   view_init_menus (view);
@@ -1218,14 +1415,15 @@ create_view (Buffer *buffer)
 }
 
 int
-main(int argc, char** argv)
+main (int argc, char** argv)
 {
   Buffer *buffer;
   View *view;
   int i;
   
-  gtk_init(&argc, &argv);
-
+  gtk_init (&argc, &argv);
+  gdk_rgb_init (); /* FIXME remove this */
+  
   buffer = create_buffer ();
   view = create_view (buffer);
   buffer_unref (buffer);
@@ -1254,7 +1452,7 @@ main(int argc, char** argv)
     }
   pop_active_window ();
   
-  gtk_main();
+  gtk_main ();
 
   return 0;
 }
index 884ed0f887b8cbeff1dd16f846a092edc78b3477..8047dc62df3adb4d3d55c26764ce5dc4c40cfd5c 100644 (file)
@@ -5,72 +5,72 @@
 #include <gtk/gtk.h>
 #include "gtktextbtree.h"
 
-static void fill_buffer(GtkTextBuffer *buffer);
+static void fill_buffer (GtkTextBuffer *buffer);
 
-static void run_tests(GtkTextBuffer *buffer);
+static void run_tests (GtkTextBuffer *buffer);
 
 int
-main(int argc, char** argv)
+main (int argc, char** argv)
 {
   GtkTextBuffer *buffer;
   int n;
   gunichar ch;
   GtkTextIter start, end;
   
-  gtk_init(&argc, &argv);
+  gtk_init (&argc, &argv);
 
   /* Check UTF8 unknown char thing */
-  g_assert(g_utf8_strlen (gtk_text_unknown_char_utf8, 3) == 1);
+  g_assert (g_utf8_strlen (gtk_text_unknown_char_utf8, 3) == 1);
   ch = g_utf8_get_char (gtk_text_unknown_char_utf8);
-  g_assert(ch == gtk_text_unknown_char);
+  g_assert (ch == gtk_text_unknown_char);
   
   /* First, we turn on btree debugging. */
   gtk_debug_flags |= GTK_DEBUG_TEXT;
 
   /* Create a buffer */
-  buffer = gtk_text_buffer_new(NULL);
+  buffer = gtk_text_buffer_new (NULL);
 
   /* Check that buffer starts with one empty line and zero chars */
   
-  n = gtk_text_buffer_get_line_count(buffer);
+  n = gtk_text_buffer_get_line_count (buffer);
   if (n != 1)
-    g_error("%d lines, expected 1", n);
+    g_error ("%d lines, expected 1", n);
   
-  n = gtk_text_buffer_get_char_count(buffer);
+  n = gtk_text_buffer_get_char_count (buffer);
   if (n != 1)
-    g_error("%d chars, expected 1", n);
+    g_error ("%d chars, expected 1", n);
   
   /* Run gruesome alien test suite on buffer */
-  run_tests(buffer);
+  run_tests (buffer);
   
   /* Put stuff in the buffer */
 
-  fill_buffer(buffer);
+  fill_buffer (buffer);
 
   /* Subject stuff-bloated buffer to further torment */
-  run_tests(buffer);
+  run_tests (buffer);
 
   /* Delete all stuff from the buffer */
-  gtk_text_buffer_get_bounds(buffer, &start, &end);
-  gtk_text_buffer_delete(buffer, &start, &end);
+  gtk_text_buffer_get_bounds (buffer, &start, &end);
+  gtk_text_buffer_delete (buffer, &start, &end);
 
   /* Check buffer for emptiness (note that a single
      empty line always remains in the buffer) */
-  n = gtk_text_buffer_get_line_count(buffer);
+  n = gtk_text_buffer_get_line_count (buffer);
   if (n != 1)
-    g_error("%d lines, expected 1", n);
+    g_error ("%d lines, expected 1", n);
   
-  n = gtk_text_buffer_get_char_count(buffer);
+  n = gtk_text_buffer_get_char_count (buffer);
   if (n != 1)
-    g_error("%d chars, expected 1", n);
+    g_error ("%d chars, expected 1", n);
 
-  run_tests(buffer);
+  run_tests (buffer);
   
   return 0;
 }
 
 static void
-run_tests(GtkTextBuffer *buffer)
+run_tests (GtkTextBuffer *buffer)
 {
   GtkTextIter iter;
   GtkTextIter start;
@@ -80,149 +80,151 @@ run_tests(GtkTextBuffer *buffer)
   gint num_chars;
   GtkTextMark *bar_mark;
   
-  gtk_text_buffer_get_bounds(buffer, &start, &end);
+  gtk_text_buffer_get_bounds (buffer, &start, &end);
   
   /* Check that walking the tree via chars and via indexes produces
    * the same number of indexable locations.
    */
-  num_chars = gtk_text_buffer_get_char_count(buffer);
+  num_chars = gtk_text_buffer_get_char_count (buffer);
   iter = start;
-  bar_mark = gtk_text_buffer_create_mark(buffer, "bar", &iter, FALSE);
+  bar_mark = gtk_text_buffer_create_mark (buffer, "bar", &iter, FALSE);
   i = 0;
   while (i < num_chars)
     {
       GtkTextIter current;
       GtkTextMark *foo_mark;
       
-      gtk_text_buffer_get_iter_at_char(buffer, &current, i);
+      gtk_text_buffer_get_iter_at_offset (buffer, &current, i);
 
-      if (!gtk_text_iter_equal(&iter, &current))
+      if (!gtk_text_iter_equal (&iter, &current))
         {
-          g_error("get_char_index didn't return current iter");
+          g_error ("get_char_index didn't return current iter");
         }
 
-      j = gtk_text_iter_get_char_index(&iter);
+      j = gtk_text_iter_get_offset (&iter);
 
       if (i != j)
         {
-          g_error("iter converted to %d not %d", j, i);
+          g_error ("iter converted to %d not %d", j, i);
         }
 
       /* get/set mark */
-      gtk_text_buffer_get_iter_at_mark(buffer, &mark, bar_mark);
+      gtk_text_buffer_get_iter_at_mark (buffer, &mark, bar_mark);
 
-      if (!gtk_text_iter_equal(&iter, &mark))
+      if (!gtk_text_iter_equal (&iter, &mark))
         {
-          gtk_text_iter_spew(&iter, "iter");
-          gtk_text_iter_spew(&mark, "mark");
-          g_error("Mark not moved to the right place.");
+          gtk_text_iter_spew (&iter, "iter");
+          gtk_text_iter_spew (&mark, "mark");
+          g_error ("Mark not moved to the right place.");
         }
       
-      foo_mark = gtk_text_buffer_create_mark(buffer, "foo", &iter, FALSE);
-      gtk_text_buffer_get_iter_at_mark(buffer, &mark, foo_mark);
-      gtk_text_buffer_delete_mark(buffer, foo_mark);
+      foo_mark = gtk_text_buffer_create_mark (buffer, "foo", &iter, FALSE);
+      gtk_text_buffer_get_iter_at_mark (buffer, &mark, foo_mark);
+      gtk_text_buffer_delete_mark (buffer, foo_mark);
       
-      if (!gtk_text_iter_equal(&iter, &mark))
+      if (!gtk_text_iter_equal (&iter, &mark))
         {
-          gtk_text_iter_spew(&iter, "iter");
-          gtk_text_iter_spew(&mark, "mark");
-          g_error("Mark not created in the right place.");
+          gtk_text_iter_spew (&iter, "iter");
+          gtk_text_iter_spew (&mark, "mark");
+          g_error ("Mark not created in the right place.");
         }
+
+      if (gtk_text_iter_is_last (&iter))
+        g_error ("iterators ran out before chars (offset %d of %d)",
+                 i, num_chars);
       
-      if (!gtk_text_iter_forward_char(&iter))
-        g_error("iterators ran out before chars");      
+      gtk_text_iter_next_char (&iter);
 
-      gtk_text_buffer_move_mark(buffer, bar_mark, &iter);
+      gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
       
       ++i;
     }
 
-  if (!gtk_text_iter_equal(&iter, &end))
-    g_error("Iterating over all chars didn't end with the end iter");
+  if (!gtk_text_iter_equal (&iter, &end))
+    g_error ("Iterating over all chars didn't end with the end iter");
 
   /* Do the tree-walk backward 
    */
-  num_chars = gtk_text_buffer_get_char_count(buffer);
-  gtk_text_buffer_get_iter_at_char(buffer, &iter, -1);
+  num_chars = gtk_text_buffer_get_char_count (buffer);
+  gtk_text_buffer_get_iter_at_offset (buffer, &iter, -1);
 
-  gtk_text_buffer_move_mark(buffer, bar_mark, &iter);
+  gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
   
   i = num_chars;
 
-  if (!gtk_text_iter_equal(&iter, &end))
-    g_error("iter at char -1 is not equal to the end iterator");
+  if (!gtk_text_iter_equal (&iter, &end))
+    g_error ("iter at char -1 is not equal to the end iterator");
   
   while (i >= 0)
     {
       GtkTextIter current;
       GtkTextMark *foo_mark;
       
-      gtk_text_buffer_get_iter_at_char(buffer, &current, i);
+      gtk_text_buffer_get_iter_at_offset (buffer, &current, i);
 
-      if (!gtk_text_iter_equal(&iter, &current))
+      if (!gtk_text_iter_equal (&iter, &current))
         {
-          g_error("get_char_index didn't return current iter while going backward");
+          g_error ("get_char_index didn't return current iter while going backward");
         }
-      j = gtk_text_iter_get_char_index(&iter);
+      j = gtk_text_iter_get_offset (&iter);
 
       if (i != j)
         {
-          g_error("going backward, iter converted to %d not %d", j, i);
+          g_error ("going backward, iter converted to %d not %d", j, i);
         }
 
       /* get/set mark */
-      gtk_text_buffer_get_iter_at_mark(buffer, &mark, bar_mark);
+      gtk_text_buffer_get_iter_at_mark (buffer, &mark, bar_mark);
 
-      if (!gtk_text_iter_equal(&iter, &mark))
+      if (!gtk_text_iter_equal (&iter, &mark))
         {
-          gtk_text_iter_spew(&iter, "iter");
-          gtk_text_iter_spew(&mark, "mark");
-          g_error("Mark not moved to the right place.");
+          gtk_text_iter_spew (&iter, "iter");
+          gtk_text_iter_spew (&mark, "mark");
+          g_error ("Mark not moved to the right place.");
         }
       
-      foo_mark = gtk_text_buffer_create_mark(buffer, "foo", &iter, FALSE);
-      gtk_text_buffer_get_iter_at_mark(buffer, &mark, foo_mark);
-      gtk_text_buffer_delete_mark(buffer, foo_mark);
+      foo_mark = gtk_text_buffer_create_mark (buffer, "foo", &iter, FALSE);
+      gtk_text_buffer_get_iter_at_mark (buffer, &mark, foo_mark);
+      gtk_text_buffer_delete_mark (buffer, foo_mark);
       
-      if (!gtk_text_iter_equal(&iter, &mark))
+      if (!gtk_text_iter_equal (&iter, &mark))
         {
-          gtk_text_iter_spew(&iter, "iter");
-          gtk_text_iter_spew(&mark, "mark");
-          g_error("Mark not created in the right place.");
+          gtk_text_iter_spew (&iter, "iter");
+          gtk_text_iter_spew (&mark, "mark");
+          g_error ("Mark not created in the right place.");
         }
       
       if (i > 0)
         {
-          if (!gtk_text_iter_backward_char(&iter))
-            g_error("iterators ran out before char indexes");
+          if (!gtk_text_iter_prev_char (&iter))
+            g_error ("iterators ran out before char indexes");
 
-          gtk_text_buffer_move_mark(buffer, bar_mark, &iter);
+          gtk_text_buffer_move_mark (buffer, bar_mark, &iter);
         }
       else
         {
-          if (gtk_text_iter_backward_char(&iter))
-            g_error("went backward from 0?");
+          if (gtk_text_iter_prev_char (&iter))
+            g_error ("went backward from 0?");
         }
       
       --i;
     }
   
-  if (!gtk_text_iter_equal(&iter, &start))
-    g_error("Iterating backward over all chars didn't end with the start iter");
+  if (!gtk_text_iter_equal (&iter, &start))
+    g_error ("Iterating backward over all chars didn't end with the start iter");
 
   /*
    * Check that get_line_count returns the same number of lines
    * as walking the tree by line
    */
   i = 1; /* include current (first) line */
-  gtk_text_buffer_get_iter_at_line(buffer, &iter, 0);
-  while (gtk_text_iter_forward_line(&iter))
+  gtk_text_buffer_get_iter_at_line (buffer, &iter, 0);
+  while (gtk_text_iter_forward_line (&iter))
     ++i;
-
-  /* Add 1 to the line count, because 'i' counts the end-iterator line */
-  if (i != gtk_text_buffer_get_line_count(buffer) + 1)
-    g_error("Counted %d lines, buffer has %d", i,
-            gtk_text_buffer_get_line_count(buffer) + 1);
+  
+  if (i != gtk_text_buffer_get_line_count (buffer))
+    g_error ("Counted %d lines, buffer has %d", i,
+            gtk_text_buffer_get_line_count (buffer));
 }
 
 
@@ -252,7 +254,7 @@ static char  *book_closed_xpm[] = {
 "                "};
 
 static void
-fill_buffer(GtkTextBuffer *buffer)
+fill_buffer (GtkTextBuffer *buffer)
 {
   GtkTextTag *tag;
   GdkColor color, color2;
@@ -262,65 +264,65 @@ fill_buffer(GtkTextBuffer *buffer)
   GdkBitmap *mask;
   int i;
   
-  tag = gtk_text_buffer_create_tag(buffer, "fg_blue");
+  tag = gtk_text_buffer_create_tag (buffer, "fg_blue");
 
   color.red = color.green = 0;
   color.blue = 0xffff;
   color2.red = 0xfff;
   color2.blue = 0x0;
   color2.green = 0;
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                  "foreground_gdk", &color,
                  "background_gdk", &color2,
                  "font", "-*-courier-bold-r-*-*-30-*-*-*-*-*-*-*",
                  NULL);
 
-  tag = gtk_text_buffer_create_tag(buffer, "fg_red");
+  tag = gtk_text_buffer_create_tag (buffer, "fg_red");
 
   color.blue = color.green = 0;
   color.red = 0xffff;
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                  "offset", -4,
                  "foreground_gdk", &color,
                  NULL);
 
-  tag = gtk_text_buffer_create_tag(buffer, "bg_green");
+  tag = gtk_text_buffer_create_tag (buffer, "bg_green");
 
   color.blue = color.red = 0;
   color.green = 0xffff;
-  gtk_object_set(GTK_OBJECT(tag),
+  gtk_object_set (GTK_OBJECT (tag),
                  "background_gdk", &color,
                  "font", "-*-courier-bold-r-*-*-10-*-*-*-*-*-*-*",
                  NULL);
 
   pixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL,
-                                                  gtk_widget_get_default_colormap(),
+                                                  gtk_widget_get_default_colormap (),
                                                   &mask,
                                                   NULL, book_closed_xpm);
   
-  g_assert(pixmap != NULL);
+  g_assert (pixmap != NULL);
   
   i = 0;
   while (i < 10)
     {
       gchar *str;
 
-      gtk_text_buffer_get_iter_at_char(buffer, &iter, 0);
+      gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
       
       gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
 
-      gtk_text_buffer_get_iter_at_char(buffer, &iter, 1);
+      gtk_text_buffer_get_iter_at_offset (buffer, &iter, 1);
       
       gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
       
-      str = g_strdup_printf("%d Hello World!\nwoo woo woo woo woo woo woo woo\n",
+      str = g_strdup_printf ("%d Hello World!\nwoo woo woo woo woo woo woo woo\n",
                             i);
       
-      gtk_text_buffer_insert(buffer, &iter, str, -1);
+      gtk_text_buffer_insert (buffer, &iter, str, -1);
 
-      g_free(str);
+      g_free (str);
       
-      gtk_text_buffer_insert(buffer, &iter,
+      gtk_text_buffer_insert (buffer, &iter,
                               "(Hello World!)\nfoo foo Hello this is some text we are using to text word wrap. It has punctuation! gee; blah - hmm, great.\nnew line\n\n"
                               /* This is UTF8 stuff, Emacs doesn't
                                  really know how to display it */
@@ -330,64 +332,64 @@ fill_buffer(GtkTextBuffer *buffer)
       gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
       gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
       
-      gtk_text_buffer_get_iter_at_char(buffer, &iter, 4);
+      gtk_text_buffer_get_iter_at_offset (buffer, &iter, 4);
       
       gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
 
-      gtk_text_buffer_get_iter_at_char(buffer, &iter, 7);
+      gtk_text_buffer_get_iter_at_offset (buffer, &iter, 7);
       
       gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
 
-      gtk_text_buffer_get_iter_at_char(buffer, &iter, 8);
+      gtk_text_buffer_get_iter_at_offset (buffer, &iter, 8);
       
       gtk_text_buffer_insert_pixmap (buffer, &iter, pixmap, mask);
 
-      gtk_text_buffer_get_iter_at_line_char(buffer, &iter, 0, 8);
+      gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 0, 8);
       iter2 = iter;
-      gtk_text_iter_forward_chars(&iter2, 10);
+      gtk_text_iter_forward_chars (&iter2, 10);
 
-      gtk_text_buffer_apply_tag(buffer, "fg_blue", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);
 
-      gtk_text_iter_forward_chars(&iter, 7);
-      gtk_text_iter_forward_chars(&iter2, 10);
+      gtk_text_iter_forward_chars (&iter, 7);
+      gtk_text_iter_forward_chars (&iter2, 10);
       
-      gtk_text_buffer_apply_tag(buffer, "bg_green", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "bg_green", &iter, &iter2);
 
-      gtk_text_iter_forward_chars(&iter, 12);
-      gtk_text_iter_forward_chars(&iter2, 10);
+      gtk_text_iter_forward_chars (&iter, 12);
+      gtk_text_iter_forward_chars (&iter2, 10);
       
-      gtk_text_buffer_apply_tag(buffer, "bg_green", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "bg_green", &iter, &iter2);
 
-      gtk_text_iter_forward_chars(&iter, 10);
-      gtk_text_iter_forward_chars(&iter2, 15);
+      gtk_text_iter_forward_chars (&iter, 10);
+      gtk_text_iter_forward_chars (&iter2, 15);
       
-      gtk_text_buffer_apply_tag(buffer, "fg_red", &iter, &iter2);
-      gtk_text_buffer_apply_tag(buffer, "fg_blue", &iter, &iter2);      
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);      
 
-      gtk_text_iter_forward_chars(&iter, 20);
-      gtk_text_iter_forward_chars(&iter2, 20);
+      gtk_text_iter_forward_chars (&iter, 20);
+      gtk_text_iter_forward_chars (&iter2, 20);
       
-      gtk_text_buffer_apply_tag(buffer, "fg_red", &iter, &iter2);
-      gtk_text_buffer_apply_tag(buffer, "fg_blue", &iter, &iter2);      
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);      
 
-      gtk_text_iter_backward_chars(&iter, 25);
-      gtk_text_iter_forward_chars(&iter2, 5);
+      gtk_text_iter_backward_chars (&iter, 25);
+      gtk_text_iter_forward_chars (&iter2, 5);
       
-      gtk_text_buffer_apply_tag(buffer, "fg_red", &iter, &iter2);
-      gtk_text_buffer_apply_tag(buffer, "fg_blue", &iter, &iter2);      
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_red", &iter, &iter2);
+      gtk_text_buffer_apply_tag_by_name (buffer, "fg_blue", &iter, &iter2);      
 
-      gtk_text_iter_forward_chars(&iter, 15);
-      gtk_text_iter_backward_chars(&iter2, 10);
+      gtk_text_iter_forward_chars (&iter, 15);
+      gtk_text_iter_backward_chars (&iter2, 10);
 
-      gtk_text_buffer_remove_tag(buffer, "fg_red", &iter, &iter2);
-      gtk_text_buffer_remove_tag(buffer, "fg_blue", &iter, &iter2);      
+      gtk_text_buffer_remove_tag_by_name (buffer, "fg_red", &iter, &iter2);
+      gtk_text_buffer_remove_tag_by_name (buffer, "fg_blue", &iter, &iter2);      
       
       ++i;
     }
 
-  gdk_pixmap_unref(pixmap);
+  gdk_pixmap_unref (pixmap);
   if (mask)
-    gdk_bitmap_unref(mask);
+    gdk_bitmap_unref (mask);
 }